From a87c9fa315375045b3db659cbd6c6c2c330ccc0c Mon Sep 17 00:00:00 2001 From: ruan <2369127-ruany@users.noreply.gitlab.com> Date: Tue, 26 Nov 2024 18:04:20 +0200 Subject: [PATCH] Support lookup by Random ID --- check.php | 2 +- inc/obscureID.php | 140 ++++++++++++++++++++++++++++++++++++++++++++++ inc/page.php | 10 ++++ inc/settings.php | 7 +++ info.php | 7 +++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 inc/obscureID.php diff --git a/check.php b/check.php index b3a0ed7..4c72909 100644 --- a/check.php +++ b/check.php @@ -33,7 +33,7 @@ class Check { $type = $info['type']; if (!isset($uuid)) { - if (filter_var($name, FILTER_VALIDATE_FLOAT)) { + if (filter_var($name, FILTER_VALIDATE_FLOAT) || $page->is_randomid($name)) { echo "
"; $page->redirect($page->link("info.php?type=$type&id=$name"), true, false); return; diff --git a/inc/obscureID.php b/inc/obscureID.php new file mode 100644 index 0000000..621d48e --- /dev/null +++ b/inc/obscureID.php @@ -0,0 +1,140 @@ +shuffle = array(); + $this->unshuffle = array(); + + $this->shuffleSecret = $array[0]; + $this->buildShuffleTables($array[1]); + } + + public function obscure($input): string { + try { + $secret = (int)$input + $this->shuffleSecret; + $id = (string)$secret; + $id = $this->leftPadInflate($id); + + $output = ""; + $currentBlock = ""; + $firstBlock = true; + for ($i = 0, $len = strlen($id); $i < $len; $i++) { + $currentBlock .= $id[$i]; + if (strlen($currentBlock) >= self::BLOCK_SIZE) { + if (!$firstBlock) { + if ($currentBlock === "000") { + $output .= "m"; + } else if (strpos($currentBlock, "00") === 0) { + $output .= "v"; + } else if ($currentBlock[0] === "0") { + $output .= "z"; + } + } + $output .= $this->shuffleIn($currentBlock); + $currentBlock = ""; + $firstBlock = false; + } + } + if (!empty($currentBlock)) { + throw new RuntimeException(); + } + return strtoupper($output); + } catch (RuntimeException $ex) { + return "error"; + } + } + + public function reveal($input): int { + try { + $str = strtolower($input); + $output = ""; + $currentBlock = ""; + for ($i = 0, $pad = 0, $len = strlen($str); $i < $len; $i++) { + switch ($str[$i]) { + case 'm': + $pad = 3; + break; + case 'v': + $pad = 2; + break; + case 'z': + $pad = 1; + break; + default: + $currentBlock .= $str[$i]; + break; + } + if (strlen($currentBlock) >= self::BLOCK_SIZE) { + $output .= $this->shuffleOut($currentBlock, $pad); + $currentBlock = ""; + $pad = 0; + } + } + if (!empty($currentBlock)) { + throw new RuntimeException(); + } + return (int)$output - $this->shuffleSecret; + } catch (RuntimeException $ex) { + return self::ERROR; + } + } + + private function leftPadInflate($id): string { + $pad = strlen($id) % self::BLOCK_SIZE; + switch ($pad) { + case 1: + return "00$id"; + case 2: + return "0$id"; + default: + return $id; + } + } + + private function leftPadDeflate($pad, $result): string { + switch ($pad) { + case 0: + return (string)$result; + case 1: + return "0$result"; + case 2: + return "00$result"; + case 3: + return "000"; + default: + throw new RuntimeException(); + } + } + + private function buildShuffleTables($str) { + for ($i = 0; $i <= 999; $i++) { + $idx = (int)($i * 3); + $hex = substr($str, $idx, 3); + $this->shuffle[$i] = $hex; + $this->unshuffle[$hex] = $i; + } + } + + private function shuffleIn($currentBlock): string { + if (isset($this->shuffle[(int)$currentBlock])) { + return $this->shuffle[(int)$currentBlock]; + } + throw new RuntimeException("No shuffle input for $currentBlock"); + } + + private function shuffleOut($currentBlock, $pad): string { + if (isset($this->unshuffle[$currentBlock])) { + return $this->leftPadDeflate($pad, $this->unshuffle[$currentBlock]); + } + throw new RuntimeException("No shuffle output for $currentBlock"); + } +} diff --git a/inc/page.php b/inc/page.php index b478242..03ac195 100644 --- a/inc/page.php +++ b/inc/page.php @@ -37,6 +37,8 @@ class Page { $this->name = $name; + $this->obscureID = null; + $this->type = null; $this->table = null; $this->title = null; @@ -87,6 +89,10 @@ class Page { } } } + if ($cfg->random_secret !== '') { + require_once './inc/obscureID.php'; + $this->obscureID = new ObscureID($cfg->random_secret); + } $argc = count($this->args); $this->page = 1; $page = "1"; @@ -444,6 +450,10 @@ class Page { } else die; } + function is_randomid($str) { + return $this->obscureID !== null && preg_match("/(?i)^[0-9a-fmvz]+$/", $str); + } + /** * Returns true if a string should be treated as a UUID. * @param $str diff --git a/inc/settings.php b/inc/settings.php index e90860b..c5c25a2 100644 --- a/inc/settings.php +++ b/inc/settings.php @@ -27,6 +27,13 @@ class Settings { // $this->name_link = 'https://example.com'; $this->name_link = 'index.php'; + // If you'd like to use random IDs generated by the plugin from the web interface: + // First, run the following command from your server console: + // > litebans reveal web + // This will dump a large string (1234:abc...) which can be pasted here. + // (Note: this feature requires LiteBans version 2.16.2 or later.) + $this->random_secret = ''; + // Show server scope column? $this->show_server_scope = false; diff --git a/info.php b/info.php index 684d3ef..a5d5958 100644 --- a/info.php +++ b/info.php @@ -143,6 +143,13 @@ count($args) >= 2 && is_string($args[0]) && is_string($args[1]) or die($page->t( $type = $args[0]; $id = $args[1]; +if ($page->is_randomid($id)) { + $reveal = $page->obscureID->reveal($id); + if ($reveal >= 0) { + $id = $reveal; + } +} + $page->set_info($page->type_info($type)); ($page->type !== null) or die("Unknown page type requested");