Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie data #229

Open
wants to merge 35 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3e2e59e
Cookie added
ismaileke Jul 28, 2024
963c533
Cookie added 2
ismaileke Jul 28, 2024
c22a7d1
Update OpenConnectionRequest2.php
ismaileke Jul 28, 2024
7425ec5
extra byte
ismaileke Jul 28, 2024
80e89f0
some fixes
ismaileke Jul 29, 2024
c58e264
updated unconnected message handler
ismaileke Jul 29, 2024
967555e
oops
ismaileke Jul 29, 2024
78f5cf5
Update OpenConnectionRequest2.php
ismaileke Jul 29, 2024
3cdf46e
Cookie Class
ismaileke Jul 30, 2024
1c94a8c
againagainagain
ismaileke Jul 30, 2024
440196c
Update Cookie.php
ismaileke Jul 30, 2024
1287f4c
Update Cookie.php
ismaileke Jul 30, 2024
3764e4b
for now
ismaileke Aug 3, 2024
312e11e
fix
ismaileke Aug 3, 2024
9078818
some fixes
ismaileke Aug 3, 2024
9c11bb4
okay
ismaileke Aug 3, 2024
ba4c754
is it right to add that lol
ismaileke Aug 3, 2024
9555243
client supports security
ismaileke Aug 7, 2024
ec8532b
added static function
ismaileke Aug 8, 2024
884bbff
non-static funcs
ismaileke Aug 9, 2024
b6c85e7
fix nullable
ismaileke Aug 9, 2024
15d1b13
use method
ismaileke Aug 9, 2024
75e8526
i forgot
ismaileke Aug 9, 2024
ff2a37e
fix but not finished
ismaileke Aug 9, 2024
8e6c677
uhhh
ismaileke Aug 9, 2024
f8250af
short usage
ismaileke Aug 10, 2024
df75ce4
Update src/protocol/OpenConnectionReply1.php
ismaileke Aug 10, 2024
64cb140
some fixes are not yet complete
ismaileke Aug 13, 2024
b9bb269
random_int
ismaileke Aug 13, 2024
65e2da8
Limits
ismaileke Aug 13, 2024
0e8b732
new name CookieCache
ismaileke Aug 13, 2024
bd80d49
delete the cookie when player log out
ismaileke Sep 20, 2024
cb35ab3
CookieCache::check() fix?
ismaileke Sep 20, 2024
41ac282
snake case :|
ismaileke Sep 20, 2024
7d1586f
pls gimme blue tick
ismaileke Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/protocol/OpenConnectionReply1.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@

namespace raklib\protocol;

use function is_int;

class OpenConnectionReply1 extends OfflineMessage{
public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REPLY_1;

public int $serverID;
public bool $serverSecurity = false;
public bool $serverSecurity;
ismaileke marked this conversation as resolved.
Show resolved Hide resolved
public ?int $cookie;
public int $mtuSize;

public static function create(int $serverId, bool $serverSecurity, int $mtuSize) : self{
public static function create(int $serverId, bool $serverSecurity, ?int $cookie = null, int $mtuSize) : self{
$result = new self;
$result->serverID = $serverId;
$result->serverSecurity = $serverSecurity;
$result->cookie = $cookie;
$result->mtuSize = $mtuSize;
return $result;
}
Expand All @@ -35,13 +39,19 @@ protected function encodePayload(PacketSerializer $out) : void{
$this->writeMagic($out);
$out->putLong($this->serverID);
$out->putByte($this->serverSecurity ? 1 : 0);
if ($this->serverSecurity && is_int($this->cookie)) {
ismaileke marked this conversation as resolved.
Show resolved Hide resolved
$out->putInt($this->cookie);
}
$out->putShort($this->mtuSize);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->readMagic($in);
$this->serverID = $in->getLong();
$this->serverSecurity = $in->getByte() !== 0;
if ($this->serverSecurity) {
$this->cookie = $in->getInt();
}
ismaileke marked this conversation as resolved.
Show resolved Hide resolved
$this->mtuSize = $in->getShort();
}
}
11 changes: 11 additions & 0 deletions src/protocol/OpenConnectionRequest2.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,34 @@
namespace raklib\protocol;

use raklib\utils\InternetAddress;
use raklib\utils\Cookie;

class OpenConnectionRequest2 extends OfflineMessage{
public static $ID = MessageIdentifiers::ID_OPEN_CONNECTION_REQUEST_2;

public int $cookie = 0;
public int $clientID;
public bool $clientSupportsSecurity = false; // Always false for the vanilla client.
public InternetAddress $serverAddress;
public int $mtuSize;

protected function encodePayload(PacketSerializer $out) : void{
$this->writeMagic($out);
if (Cookie::hasServerSecurity()) {
$out->putInt($this->cookie);
$out->putBool($this->clientSupportsSecurity);
}
$out->putAddress($this->serverAddress);
$out->putShort($this->mtuSize);
$out->putLong($this->clientID);
}

protected function decodePayload(PacketSerializer $in) : void{
$this->readMagic($in);
if (Cookie::hasServerSecurity()) {
$this->cookie = $in->getInt();
$this->clientSupportsSecurity = $in->getBool();
}
$this->serverAddress = $in->getAddress();
$this->mtuSize = $in->getShort();
$this->clientID = $in->getLong();
Expand Down
16 changes: 15 additions & 1 deletion src/server/UnconnectedMessageHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use raklib\protocol\UnconnectedPingOpenConnections;
use raklib\protocol\UnconnectedPong;
use raklib\utils\InternetAddress;
use raklib\utils\Cookie;
use function get_class;
use function min;
use function ord;
Expand Down Expand Up @@ -81,10 +82,16 @@ private function handle(OfflineMessage $packet, InternetAddress $address) : bool
$this->server->sendPacket(IncompatibleProtocolVersion::create($this->protocolAcceptor->getPrimaryVersion(), $this->server->getID()), $address);
$this->server->getLogger()->notice("Refused connection from $address due to incompatible RakNet protocol version (version $packet->protocol)");
}else{
$cookie = null;
if (Cookie::hasServerSecurity()) {
Cookie::add($address);
$cookie = Cookie::get($address);
}
//IP header size (20 bytes) + UDP header size (8 bytes)
$this->server->sendPacket(OpenConnectionReply1::create($this->server->getID(), false, $packet->mtuSize + 28), $address);
$this->server->sendPacket(OpenConnectionReply1::create($this->server->getID(), Cookie::hasServerSecurity(), $cookie, $packet->mtuSize + 28), $address);
}
}elseif($packet instanceof OpenConnectionRequest2){
// The client may not send such data even though serverSecurity is enabled, and if we try to decode this, we may encounter an error
if($packet->serverAddress->getPort() === $this->server->getPort() or !$this->server->portChecking){
if($packet->mtuSize < Session::MIN_MTU_SIZE){
$this->server->getLogger()->debug("Not creating session for $address due to bad MTU size $packet->mtuSize");
Expand All @@ -97,6 +104,13 @@ private function handle(OfflineMessage $packet, InternetAddress $address) : bool
$this->server->getLogger()->debug("Not creating session for $address due to session already opened");
return true;
}
if (Cookie::hasServerSecurity()) {
if (!Cookie::check($address, $packet->cookie)) {
// Disconnect if OpenConnectionReply1 and the cookie in the OpenCnnectionRequest2 packet do not match
$this->server->getLogger()->debug("Not creating session for $address due to session mismatched cookies");
return true;
}
}
$mtuSize = min($packet->mtuSize, $this->server->getMaxMtuSize()); //Max size, do not allow creating large buffers to fill server memory
$this->server->sendPacket(OpenConnectionReply2::create($this->server->getID(), $address, $mtuSize, false), $address);
$this->server->createSession($address, $packet->clientID, $mtuSize);
Expand Down
66 changes: 66 additions & 0 deletions src/utils/Cookie.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of RakLib.
* Copyright (C) 2014-2022 PocketMine Team <https://github.com/pmmp/RakLib>
*
* RakLib is not affiliated with Jenkins Software LLC nor RakNet.
*
* RakLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/

declare(strict_types=1);

namespace raklib\utils;

use raklib\utils\InternetAddress;
use pocketmine\utils\Binary;
use function mt_rand;
use function crc32;

final class Cookie{

public static bool $serverHasSecurity = false;

/**
* @var array<string, int> $cookies
*/
private static array $cookies = [];

public static function get(InternetAddress $address) : int{
if (isset(self::$cookies[$address->toString()])) {
return self::$cookies[$address->toString()];
}
return 0;
}

public static function hasServerSecurity () : bool {
return self::$serverHasSecurity;
ismaileke marked this conversation as resolved.
Show resolved Hide resolved
}

public static function check(InternetAddress $address, int $cookie) : bool{
$addressStr = $address->toString();

if (isset(self::$cookies[$addressStr])) {
// If it checks the Cookie, it means that it is in the OpenConnectionRequest2 phase and we can delete it from memory
unset(self::$cookies[$addressStr]);
if (self::$cookies[$addressStr] == $cookie) {
return true;
}
} // Is there any chance that this is something else?
return false;
}

public static function add(InternetAddress $address) : void{
if (!isset(self::$cookies[$address->toString()])) {
self::$cookies[$address->toString()] = self::generate($address);
}
}

private static function generate(InternetAddress $address) : int{
return crc32(Binary::writeLInt(mt_rand(0, 0xFFFFFFFF)) . Binary::writeLShort($address->getPort()) . $address->getIp());
}
}
Loading