mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-16 18:59:00 +00:00
more jsonmapper models for login
This commit is contained in:
parent
4bb93eeca7
commit
57908586bd
@ -29,6 +29,8 @@ use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
|
|||||||
use pocketmine\network\mcpe\JwtException;
|
use pocketmine\network\mcpe\JwtException;
|
||||||
use pocketmine\network\mcpe\JwtUtils;
|
use pocketmine\network\mcpe\JwtUtils;
|
||||||
use pocketmine\network\mcpe\protocol\LoginPacket;
|
use pocketmine\network\mcpe\protocol\LoginPacket;
|
||||||
|
use pocketmine\network\mcpe\protocol\types\login\JwtChainLinkBody;
|
||||||
|
use pocketmine\network\mcpe\protocol\types\login\JwtHeader;
|
||||||
use pocketmine\scheduler\AsyncTask;
|
use pocketmine\scheduler\AsyncTask;
|
||||||
use function base64_decode;
|
use function base64_decode;
|
||||||
use function time;
|
use function time;
|
||||||
@ -106,18 +108,30 @@ class ProcessLoginTask extends AsyncTask{
|
|||||||
*/
|
*/
|
||||||
private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{
|
private function validateToken(string $jwt, ?string &$currentPublicKey, bool $first = false) : void{
|
||||||
try{
|
try{
|
||||||
[$headers, $claims, ] = JwtUtils::parse($jwt);
|
[$headersArray, $claimsArray, ] = JwtUtils::parse($jwt);
|
||||||
}catch(JwtException $e){
|
}catch(JwtException $e){
|
||||||
throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e);
|
throw new VerifyLoginException("Failed to parse JWT: " . $e->getMessage(), 0, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mapper = new \JsonMapper();
|
||||||
|
$mapper->bExceptionOnMissingData = true;
|
||||||
|
$mapper->bExceptionOnUndefinedProperty = true;
|
||||||
|
$mapper->bEnforceMapType = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
/** @var JwtHeader $headers */
|
||||||
|
$headers = $mapper->map($headersArray, new JwtHeader());
|
||||||
|
}catch(\JsonMapper_Exception $e){
|
||||||
|
throw new VerifyLoginException("Invalid JWT header: " . $e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
if($currentPublicKey === null){
|
if($currentPublicKey === null){
|
||||||
if(!$first){
|
if(!$first){
|
||||||
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey");
|
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.missingKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
//First link, check that it is self-signed
|
//First link, check that it is self-signed
|
||||||
$currentPublicKey = $headers["x5u"];
|
$currentPublicKey = $headers->x5u;
|
||||||
}
|
}
|
||||||
|
|
||||||
$derPublicKeySerializer = new DerPublicKeySerializer();
|
$derPublicKeySerializer = new DerPublicKeySerializer();
|
||||||
@ -143,16 +157,28 @@ class ProcessLoginTask extends AsyncTask{
|
|||||||
$this->authenticated = true; //we're signed into xbox live
|
$this->authenticated = true; //we're signed into xbox live
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mapper = new \JsonMapper();
|
||||||
|
$mapper->bExceptionOnUndefinedProperty = false; //we only care about the properties we're using in this case
|
||||||
|
$mapper->bExceptionOnMissingData = true;
|
||||||
|
$mapper->bEnforceMapType = false;
|
||||||
|
$mapper->bRemoveUndefinedAttributes = true;
|
||||||
|
try{
|
||||||
|
/** @var JwtChainLinkBody $claims */
|
||||||
|
$claims = $mapper->map($claimsArray, new JwtChainLinkBody());
|
||||||
|
}catch(\JsonMapper_Exception $e){
|
||||||
|
throw new VerifyLoginException("Invalid chain link body: " . $e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
|
||||||
$time = time();
|
$time = time();
|
||||||
if(isset($claims["nbf"]) and $claims["nbf"] > $time + self::CLOCK_DRIFT_MAX){
|
if(isset($claims->nbf) and $claims->nbf > $time + self::CLOCK_DRIFT_MAX){
|
||||||
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly");
|
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooEarly");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($claims["exp"]) and $claims["exp"] < $time - self::CLOCK_DRIFT_MAX){
|
if(isset($claims->exp) and $claims->exp < $time - self::CLOCK_DRIFT_MAX){
|
||||||
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate");
|
throw new VerifyLoginException("%pocketmine.disconnect.invalidSession.tooLate");
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentPublicKey = $claims["identityPublicKey"] ?? null; //if there are further links, the next link should be signed with this
|
$currentPublicKey = $claims->identityPublicKey ?? null; //if there are further links, the next link should be signed with this
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onCompletion() : void{
|
public function onCompletion() : void{
|
||||||
|
45
src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php
Normal file
45
src/network/mcpe/protocol/types/login/JwtBodyRfc7519.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model class for JsonMapper which describes the RFC7519 standard fields in a JWT. Any of these fields might not be
|
||||||
|
* provided.
|
||||||
|
*/
|
||||||
|
class JwtBodyRfc7519{
|
||||||
|
/** @var string */
|
||||||
|
public $iss;
|
||||||
|
/** @var string */
|
||||||
|
public $sub;
|
||||||
|
/** @var string|string[] */
|
||||||
|
public $aud;
|
||||||
|
/** @var int */
|
||||||
|
public $exp;
|
||||||
|
/** @var int */
|
||||||
|
public $nbf;
|
||||||
|
/** @var int */
|
||||||
|
public $iat;
|
||||||
|
/** @var string */
|
||||||
|
public $jti;
|
||||||
|
}
|
33
src/network/mcpe/protocol/types/login/JwtChainLinkBody.php
Normal file
33
src/network/mcpe/protocol/types/login/JwtChainLinkBody.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model for JsonMapper exposing the data in the login JWT chain links.
|
||||||
|
* TODO: extend this with more complete models
|
||||||
|
*/
|
||||||
|
final class JwtChainLinkBody extends JwtBodyRfc7519{
|
||||||
|
/** @var string */
|
||||||
|
public $identityPublicKey;
|
||||||
|
}
|
37
src/network/mcpe/protocol/types/login/JwtHeader.php
Normal file
37
src/network/mcpe/protocol/types/login/JwtHeader.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace pocketmine\network\mcpe\protocol\types\login;
|
||||||
|
|
||||||
|
final class JwtHeader{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @required
|
||||||
|
*/
|
||||||
|
public $alg;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @required
|
||||||
|
*/
|
||||||
|
public $x5u;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user