From 8f2371b3b1a53a8af4d3bae7f80397f307b8c48b Mon Sep 17 00:00:00 2001 From: anzz1 Date: Sun, 30 Jan 2022 00:38:28 +0200 Subject: [PATCH 01/18] Improvements for account creation script * Properly return error messages instead of hanging in "Please wait ..." indefinitely * Add check if database connection succeeded before advancing, return error if not * Add timeout for database connection, 5 seconds (configurable) * Add database port option --- Trinity Account Creator/js/script.js | 49 ++++++++++++------- Trinity Account Creator/php/createAccount.php | 9 +++- Trinity Account Creator/php/db.php | 22 ++++++--- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/Trinity Account Creator/js/script.js b/Trinity Account Creator/js/script.js index 2a6b9de..ee90677 100644 --- a/Trinity Account Creator/js/script.js +++ b/Trinity Account Creator/js/script.js @@ -23,26 +23,36 @@ function submitForm() { // Create a callback function. xhr.onreadystatechange = function() { - if (xhr.readyState == 4 && xhr.status == 200) { - // Transaction was successful. - if (xhr.responseText == '0') { - // Reset the form first. - document.getElementById('accountForm').reset(); + if (xhr.readyState == 4) { + if (xhr.status == 200) { + // Transaction was successful. + if (xhr.responseText == '0') { + // Reset the form first. + document.getElementById('accountForm').reset(); - // Update the status message. + // Update the status message. + document.getElementById('statusMessage').value = + 'Account created successfully!'; + document.getElementById('statusMessage').style.color = 'green'; + } else if (xhr.responseText == '1') { + document.getElementById('statusMessage').value = 'Email is invalid.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '2') { + document.getElementById('statusMessage').value = + 'Account already exists.'; + document.getElementById('statusMessage').style.color = 'red'; + } else if (xhr.responseText == '3') { + document.getElementById('statusMessage').value = + 'Connection failed.'; + document.getElementById('statusMessage').style.color = 'red'; + } else { + document.getElementById('statusMessage').value = + 'Unknown error occurred.'; + document.getElementById('statusMessage').style.color = 'red'; + } + } else { document.getElementById('statusMessage').value = - 'Account created successfully!'; - document.getElementById('statusMessage').style.color = 'green'; - } else if (xhr.responseText == '1') { - document.getElementById('statusMessage').value = 'Email is invalid.'; - document.getElementById('statusMessage').style.color = 'yellow'; - } else if (xhr.responseText == '2') { - document.getElementById('statusMessage').value = - 'Account already exists.'; - document.getElementById('statusMessage').style.color = 'red'; - } else if (xhr.responseText == '3') { - document.getElementById('statusMessage').value = - 'Unknown error occurred.
Please try again.'; + 'Unknown error occurred.'; document.getElementById('statusMessage').style.color = 'red'; } } @@ -59,3 +69,6 @@ $('#accountForm').submit(function(event) { // Cancel the form submission, so we can use AJAX instead. event.preventDefault(); }); + +// Reset status message on page reload +document.getElementById('statusMessage').value = ''; diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index 30db93d..a6065dd 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -4,6 +4,11 @@ $db = new db(); + if (!$db->isOpen()) { + echo "3"; // Connection failed + return; + } + // Get POST data and validate. if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = validateInput($_POST['username']); @@ -63,11 +68,11 @@ } catch(PDOException $e) { - echo "3"; // Update status message with unknown error occurred. + echo "4"; // Update status message with unknown error occurred. error_log("PDO Database error occurred: " . $e->getMessage()); } catch (Exception $e) { - echo "3"; // Update status message with unknown error occurred. + echo "4"; // Update status message with unknown error occurred. error_log("Unknown error occurred: " . $e->getMessage()); } diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 9e2dd11..67d4f94 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -6,9 +6,10 @@ class db { /* --------------------- ONLY EDIT THE VALUES BELOW THIS LINE --------------------- */ - private $host = "localhost"; // IP or hostname of your server. - private $username = "username"; // Database username. - private $password = "password"; // Database password. + private $host = "localhost"; // IP or hostname of your database server. + private $port = "3306"; // Port of your database server. + private $username = "trinity"; // Database username. + private $password = "trinity"; // Database password. private $dbname = "auth"; // Database name (i.e. "auth"). /* --------------------- DO NOT EDIT ANYTHING BELOW THIS LINE --------------------- */ @@ -19,15 +20,16 @@ function __construct() { try { // Establish a new connection to the database. - $connection = new PDO("mysql:host=$this->host;dbname=$this->dbname", $this->username, $this->password); - - // Set the PDO error mode to Exception. - $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $connection = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname", $this->username, $this->password, + array( + PDO::ATTR_TIMEOUT => 5, // Timeout is 5 seconds + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // Set PDO error mode to Exception. + )); $this->conn = $connection; } catch (PDOException $e) { - echo "Connection failed: " . $e->getMessage(); + error_log("Connection failed: " . $e->getMessage()); } } @@ -128,6 +130,10 @@ public function getRegistrationData($username, $password) return array($salt, $verifier); } + public function isOpen() { + return ($this->conn != null); + } + // Close the database connection. public function close() { $this->conn = null; From ba2cc8356da7a1db4d5816b4d8d025609471abda Mon Sep 17 00:00:00 2001 From: anzz1 Date: Sun, 30 Jan 2022 01:04:12 +0200 Subject: [PATCH 02/18] Update index.html example spot for realmlist info --- Trinity Account Creator/index.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Trinity Account Creator/index.html b/Trinity Account Creator/index.html index 3d3779c..0236a0d 100644 --- a/Trinity Account Creator/index.html +++ b/Trinity Account Creator/index.html @@ -72,6 +72,13 @@ /> + From c00b538d4693b49ec87bf6969645e1bad0763e8c Mon Sep 17 00:00:00 2001 From: anzz1 Date: Sun, 30 Jan 2022 03:17:10 +0200 Subject: [PATCH 03/18] more fixes --- Trinity Account Creator/js/script.js | 39 +++++++---- Trinity Account Creator/php/createAccount.php | 70 ++++++++++++------- Trinity Account Creator/php/db.php | 28 +++++--- 3 files changed, 91 insertions(+), 46 deletions(-) diff --git a/Trinity Account Creator/js/script.js b/Trinity Account Creator/js/script.js index ee90677..284c121 100644 --- a/Trinity Account Creator/js/script.js +++ b/Trinity Account Creator/js/script.js @@ -31,28 +31,41 @@ function submitForm() { document.getElementById('accountForm').reset(); // Update the status message. - document.getElementById('statusMessage').value = - 'Account created successfully!'; + document.getElementById('statusMessage').value = 'Account created successfully!'; document.getElementById('statusMessage').style.color = 'green'; } else if (xhr.responseText == '1') { - document.getElementById('statusMessage').value = 'Email is invalid.'; - document.getElementById('statusMessage').style.color = 'yellow'; + document.getElementById('statusMessage').value = 'Account already exists.'; + document.getElementById('statusMessage').style.color = 'red'; } else if (xhr.responseText == '2') { - document.getElementById('statusMessage').value = - 'Account already exists.'; + document.getElementById('statusMessage').value = 'Connection failed.'; document.getElementById('statusMessage').style.color = 'red'; } else if (xhr.responseText == '3') { - document.getElementById('statusMessage').value = - 'Connection failed.'; - document.getElementById('statusMessage').style.color = 'red'; + document.getElementById('statusMessage').value = 'Username is empty.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '4') { + document.getElementById('statusMessage').value = 'Username is invalid.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '5') { + document.getElementById('statusMessage').value = 'Username is too long.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '6') { + document.getElementById('statusMessage').value = 'Password is empty.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '7') { + document.getElementById('statusMessage').value = 'Password is invalid.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '8') { + document.getElementById('statusMessage').value = 'Email is empty.'; + document.getElementById('statusMessage').style.color = 'yellow'; + } else if (xhr.responseText == '9') { + document.getElementById('statusMessage').value = 'Email is invalid.'; + document.getElementById('statusMessage').style.color = 'yellow'; } else { - document.getElementById('statusMessage').value = - 'Unknown error occurred.'; + document.getElementById('statusMessage').value = 'Unknown error occurred.'; document.getElementById('statusMessage').style.color = 'red'; } } else { - document.getElementById('statusMessage').value = - 'Unknown error occurred.'; + document.getElementById('statusMessage').value = 'Unknown error occurred.'; document.getElementById('statusMessage').style.color = 'red'; } } diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index a6065dd..cabb4d2 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -5,28 +5,50 @@ $db = new db(); if (!$db->isOpen()) { - echo "3"; // Connection failed + echo "2"; // Connection failed return; } // Get POST data and validate. if ($_SERVER["REQUEST_METHOD"] == "POST") { - $username = validateInput($_POST['username']); - $email = validateInput($_POST['email']); - $password = validateInput($_POST['password']); + $username = trim($_POST['username']); + $email = trim($_POST['email']); + $password = $_POST['password']; } - if (!isset($username) || !is_string($username)) - throw new InvalidArgumentException("Username is invalid or empty."); - - if (!isset($password) || !is_string($password)) - throw new InvalidArgumentException("Password is invalid or empty."); + if (!isset($username) || !is_string($username) || empty($username)) { + echo "3"; // Username is empty. + return; + } + $username = validateInput($username); + if (!isset($username)) { + echo "4"; // Username is invalid. + return; + } + if (strlen($username) > 32) { + echo "5"; // Username is too long. + return; + } - if (!isset($email)) - throw new InvalidArgumentException("Email is empty."); + if (!isset($password) || !is_string($password) || empty($password)) { + echo "6"; // Password is empty. + return; + } + if (strlen($password) > 255) { + echo "7"; // Password is invalid. + return; + } + if (!isset($email)) { + echo "8"; // Email is empty. + return; + } + if (strlen($email) > 255) { + echo "9"; // Email is invalid. + return; + } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { - echo "1"; // Returns that email is invalid, to update status message. + echo "9"; // Email is invalid. return; } @@ -41,7 +63,7 @@ if ($db->getRowCount($results) > 0) { // Account already exists, inform user and stop transaction. - echo "2"; + echo "1"; // Close connection to the database. $db->close(); @@ -51,7 +73,7 @@ // If no account exists, create a new one. - // Get the SHA1 encrypted password. + // Get the SRP6 salt and verifier tokens list($salt, $verifier) = $db->getRegistrationData($username, $password); $accountCreateQuery = "INSERT INTO account(username, salt, verifier, email) VALUES(?, ?, ?, ?)"; @@ -64,25 +86,25 @@ $db->close(); // Return successful to AJAX call. - echo "0"; + echo "0"; // Account created successfully! } catch(PDOException $e) { - echo "4"; // Update status message with unknown error occurred. - error_log("PDO Database error occurred: " . $e->getMessage()); + echo "-1"; // Unknown error occured. + error_log("Database error: " . $e->getMessage()); } catch (Exception $e) { - echo "4"; // Update status message with unknown error occurred. - error_log("Unknown error occurred: " . $e->getMessage()); + echo "-1"; // Unknown error occured. + error_log("Unknown error: " . $e->getMessage()); } // Validates POST input data. - function validateInput($param) { - $param = trim($param); - $param = stripslashes($param); - $param = htmlspecialchars($param); + function validateInput($param) { + $valid = stripslashes($param); + $valid = htmlspecialchars($valid, ENT_QUOTES); + $valid = preg_replace('/\s+/', '', $valid); - return $param; + return ($param == $valid) ? $param : null; } ?> diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 67d4f94..23614b9 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -41,7 +41,7 @@ public function insertQuery($query, $params) { $stmt->execute($params); } catch (PDOException $e) { - error_log("Error when inserting a new account: " . $e->getMessage()); + throw $e; } } } @@ -49,12 +49,17 @@ public function insertQuery($query, $params) { // Fetches and returns the next row from the result set. public function querySingleRow($query, $params) { if ($query) { - $stmt = $this->conn->prepare($query); - $stmt->execute($params); + try { + $stmt = $this->conn->prepare($query); + $stmt->execute($params); - $row = $stmt->fetch(PDO::FETCH_ASSOC); + $row = $stmt->fetch(PDO::FETCH_ASSOC); - return $row; + return $row; + } + catch (PDOException $e) { + throw $e; + } } else return null; @@ -63,12 +68,17 @@ public function querySingleRow($query, $params) { // Returns an array containing all of the result set rows. public function queryMultiRow($query, $params) { if ($query) { - $stmt = $this->conn->prepare($query); - $stmt->execute($params); + try { + $stmt = $this->conn->prepare($query); + $stmt->execute($params); - $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); - return $results; + return $results; + } + catch (PDOException $e) { + throw $e; + } } else return null; From f37060018301d3aaa5e6d39b600beb96d772f01d Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 00:25:37 +0200 Subject: [PATCH 04/18] set charset to utf-8 --- Trinity Account Creator/php/createAccount.php | 12 +++++++++--- Trinity Account Creator/php/db.php | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index cabb4d2..bf65f32 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -1,5 +1,8 @@ getRegistrationData($username, $password); - $accountCreateQuery = "INSERT INTO account(username, salt, verifier, email) VALUES(?, ?, ?, ?)"; - $accountCreateParams = array($username, $salt, $verifier, $email); + $accountCreateQuery = "INSERT INTO account(username, salt, verifier, reg_mail, email) VALUES(?, ?, ?, ?, ?)"; + $accountCreateParams = array($username, $salt, $verifier, $email, $email); // Execute the query. $db->insertQuery($accountCreateQuery, $accountCreateParams); diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 23614b9..5ea2a39 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -1,4 +1,7 @@ host;port=$this->port;dbname=$this->dbname", $this->username, $this->password, + $connection = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=utf8", $this->username, $this->password, array( PDO::ATTR_TIMEOUT => 5, // Timeout is 5 seconds PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // Set PDO error mode to Exception. From 799580d5699def586740c51bc7b40f87063d04a5 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 00:27:14 +0200 Subject: [PATCH 05/18] default username root -> trinity --- Trinity Account Creator/php/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 5ea2a39..70f2a55 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -11,7 +11,7 @@ class db { private $host = "localhost"; // IP or hostname of your database server. private $port = "3306"; // Port of your database server. - private $username = "root"; // Database username. + private $username = "trinity"; // Database username. private $password = "trinity"; // Database password. private $dbname = "auth"; // Database name (i.e. "auth"). From 10a535c4f6a6832586df0fdea1581367500c3707 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 01:35:31 +0200 Subject: [PATCH 06/18] Encoding fixes * Use php_mbstring to properly calculate length * TrinityCore limits usernames to 16 bytes which can be low as 8 utf-8 characters, adhere to this * Password input field in 3.3.5.12340 allows max 16 characters, but it can be 16-32 bytes depending on encoding. SRP6 does not impose such a limitation so this is an oversight on the client. Have to adhere to it nevertheless --- Trinity Account Creator/js/script.js | 2 +- Trinity Account Creator/php/createAccount.php | 15 ++++++++++----- Trinity Account Creator/php/db.php | 4 ++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Trinity Account Creator/js/script.js b/Trinity Account Creator/js/script.js index 284c121..472f906 100644 --- a/Trinity Account Creator/js/script.js +++ b/Trinity Account Creator/js/script.js @@ -52,7 +52,7 @@ function submitForm() { document.getElementById('statusMessage').value = 'Password is empty.'; document.getElementById('statusMessage').style.color = 'yellow'; } else if (xhr.responseText == '7') { - document.getElementById('statusMessage').value = 'Password is invalid.'; + document.getElementById('statusMessage').value = 'Password is too long.'; document.getElementById('statusMessage').style.color = 'yellow'; } else if (xhr.responseText == '8') { document.getElementById('statusMessage').value = 'Email is empty.'; diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index bf65f32..3619bf1 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -2,7 +2,11 @@ // explicitly set charset to utf-8 ini_set('default_charset', 'utf-8'); - + if(ini_get('mbstring.func_overload')) { + ini_set('mbstring.func_overload', 0); + } + mb_internal_encoding("UTF-8"); + require_once(dirname(__FILE__) . '/db.php'); $db = new db(); @@ -28,7 +32,7 @@ echo "4"; // Username is invalid. return; } - if (strlen($username) > 32) { + if (mb_strlen($username, '8bit') > 16) { echo "5"; // Username is too long. return; } @@ -37,8 +41,9 @@ echo "6"; // Password is empty. return; } - if (strlen($password) > 255) { - echo "7"; // Password is invalid. + // password has a 16 character limit on 3.3.5.12340 client even when SRP6 does not have such limitation + if (mb_strlen($password, 'UTF-8') > 16) { + echo "7"; // Password is too long. return; } @@ -46,7 +51,7 @@ echo "8"; // Email is empty. return; } - if (strlen($email) > 255) { + if (mb_strlen($email, '8bit') > 255) { echo "9"; // Email is invalid. return; } diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 70f2a55..4763457 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -2,6 +2,10 @@ // explicitly set charset to utf-8 ini_set('default_charset', 'utf-8'); + if(ini_get('mbstring.func_overload') { + ini_set('mbstring.func_overload', 0); + } + mb_internal_encoding("UTF-8"); class db { From 1a6b4323c017a954195f9a69ade5abeb6ce922b1 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 02:05:58 +0200 Subject: [PATCH 07/18] fix typo --- Trinity Account Creator/php/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 4763457..5cde804 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -2,7 +2,7 @@ // explicitly set charset to utf-8 ini_set('default_charset', 'utf-8'); - if(ini_get('mbstring.func_overload') { + if(ini_get('mbstring.func_overload')) { ini_set('mbstring.func_overload', 0); } mb_internal_encoding("UTF-8"); From 3cb4ae5a09a382ac805bcd6f82ee81edd42de012 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 02:20:48 +0200 Subject: [PATCH 08/18] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0220e25..834255e 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,5 @@ Projects created for use with the TrinityCore World of Warcraft emulator: https: # Requirements gmp module is required to be enabled in PHP. On linux this means either `sudo apt install php-gmp` or editing the default php.ini and uncomment the `extension=gmp` line + pdo_mysql module is required to be enabled in PHP. On linux this means either `sudo apt install php-mysql` or editing the default php.ini and uncomment the `extension=pdo_mysql` line + mbstring module is required to be enabled in PHP. On linux this means either `sudo apt install php-mbstring` or editing the default php.ini and uncomment the `extension=mbstring` line From 62db0cb78e184af18f58e6d6e16ec108406a4895 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 31 Jan 2022 02:21:23 +0200 Subject: [PATCH 09/18] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 834255e..244a110 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Projects created for use with the TrinityCore World of Warcraft emulator: https://www.trinitycore.org/ # Requirements - gmp module is required to be enabled in PHP. On linux this means either `sudo apt install php-gmp` or editing the default php.ini and uncomment the `extension=gmp` line - pdo_mysql module is required to be enabled in PHP. On linux this means either `sudo apt install php-mysql` or editing the default php.ini and uncomment the `extension=pdo_mysql` line - mbstring module is required to be enabled in PHP. On linux this means either `sudo apt install php-mbstring` or editing the default php.ini and uncomment the `extension=mbstring` line + gmp module is required to be enabled in PHP. On linux this means either `sudo apt install php-gmp` or editing the default php.ini and uncomment the `extension=gmp` line + + pdo_mysql module is required to be enabled in PHP. On linux this means either `sudo apt install php-mysql` or editing the default php.ini and uncomment the `extension=pdo_mysql` line + + mbstring module is required to be enabled in PHP. On linux this means either `sudo apt install php-mbstring` or editing the default php.ini and uncomment the `extension=mbstring` line From e9ba878cc07065091bd0b441c76274747af26739 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Wed, 2 Feb 2022 23:32:20 +0200 Subject: [PATCH 10/18] Even more fixes * Scrap php_mbstring * Make absolutely sure all php options use utf-8 * fix strtoupper implementation , use own --- Trinity Account Creator/php/createAccount.php | 55 ++++++++---------- Trinity Account Creator/php/db.php | 58 +++++++++---------- Trinity Account Creator/php/vars.php | 36 ++++++++++++ 3 files changed, 88 insertions(+), 61 deletions(-) create mode 100644 Trinity Account Creator/php/vars.php diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index 3619bf1..eb64aa2 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -1,21 +1,15 @@ isOpen()) { echo "2"; // Connection failed return; } - + // Get POST data and validate. if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = trim($_POST['username']); @@ -32,26 +26,29 @@ echo "4"; // Username is invalid. return; } - if (mb_strlen($username, '8bit') > 16) { + + // username has 16 byte limit on TC server + if (strlen($username) > 16) { echo "5"; // Username is too long. return; } - + if (!isset($password) || !is_string($password) || empty($password)) { echo "6"; // Password is empty. return; } + // password has a 16 character limit on 3.3.5.12340 client even when SRP6 does not have such limitation - if (mb_strlen($password, 'UTF-8') > 16) { + if (strlen($password) > 64 || iconv_strlen($password, 'utf-8') > 16) { echo "7"; // Password is too long. return; } - + if (!isset($email)) { echo "8"; // Email is empty. return; } - if (mb_strlen($email, '8bit') > 255) { + if (strlen($email) > 255) { echo "9"; // Email is invalid. return; } @@ -60,19 +57,17 @@ return; } - $username = strtoupper($username); - $email = strtoupper($email); + $username = $db->strtoupper_az($username); + $email = $db->strtoupper_az($email); try { - // First, we need to check if the account name already exists. $accountCheckQuery = "SELECT * FROM account WHERE username = ?"; $accountCheckParams = array($username); - + $results = $db->queryMultiRow($accountCheckQuery, $accountCheckParams); - + if ($db->getRowCount($results) > 0) { - // Account already exists, inform user and stop transaction. echo "1"; @@ -81,24 +76,25 @@ return; } - + // If no account exists, create a new one. - + // Get the SRP6 salt and verifier tokens list($salt, $verifier) = $db->getRegistrationData($username, $password); - + $accountCreateQuery = "INSERT INTO account(username, salt, verifier, reg_mail, email) VALUES(?, ?, ?, ?, ?)"; $accountCreateParams = array($username, $salt, $verifier, $email, $email); - + // Execute the query. $db->insertQuery($accountCreateQuery, $accountCreateParams); - + // Close connection to the database. $db->close(); - + + error_log("Account created: '" . $username . "' '". $email . "'"); + // Return successful to AJAX call. echo "0"; // Account created successfully! - } catch(PDOException $e) { echo "-1"; // Unknown error occured. @@ -108,14 +104,13 @@ echo "-1"; // Unknown error occured. error_log("Unknown error: " . $e->getMessage()); } - + // Validates POST input data. function validateInput($param) { $valid = stripslashes($param); $valid = htmlspecialchars($valid, ENT_QUOTES); $valid = preg_replace('/\s+/', '', $valid); - + return ($param == $valid) ? $param : null; } - ?> diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 5cde804..161ea80 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -1,16 +1,9 @@ host;port=$this->port;dbname=$this->dbname;charset=utf8", $this->username, $this->password, array( PDO::ATTR_TIMEOUT => 5, // Timeout is 5 seconds PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // Set PDO error mode to Exception. )); - + $this->conn = $connection; } catch (PDOException $e) { error_log("Connection failed: " . $e->getMessage()); } } - + // Executes an INSERT query on the database. public function insertQuery($query, $params) { if ($query) { @@ -52,16 +45,16 @@ public function insertQuery($query, $params) { } } } - + // Fetches and returns the next row from the result set. public function querySingleRow($query, $params) { if ($query) { try { $stmt = $this->conn->prepare($query); $stmt->execute($params); - + $row = $stmt->fetch(PDO::FETCH_ASSOC); - + return $row; } catch (PDOException $e) { @@ -71,16 +64,16 @@ public function querySingleRow($query, $params) { else return null; } - + // Returns an array containing all of the result set rows. public function queryMultiRow($query, $params) { if ($query) { try { $stmt = $this->conn->prepare($query); $stmt->execute($params); - + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); - + return $results; } catch (PDOException $e) { @@ -90,22 +83,21 @@ public function queryMultiRow($query, $params) { else return null; } - + // Returns the row count from a PDO result set. public function getRowCount($results) { - // We can use the count() function here, because the result set is either // an associative or numerical array. if ($results) { return count($results); } } - + // Returns the last inserted row or sequence. public function getLastInsertId() { return $this->conn->lastInsertId(); } - + private function calculateSRP6Verifier($username, $password, $salt) { // algorithm constants @@ -113,7 +105,7 @@ private function calculateSRP6Verifier($username, $password, $salt) $N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16); // calculate first hash - $h1 = sha1(strtoupper($username . ':' . $password), TRUE); + $h1 = sha1($this->strtoupper_az($username . ':' . $password), TRUE); // calculate second hash $h2 = sha1($salt.$h1, TRUE); @@ -133,29 +125,33 @@ private function calculateSRP6Verifier($username, $password, $salt) // done! return $verifier; } - + // Returns SRP6 parameters to register this username/password combination with public function getRegistrationData($username, $password) { // generate a random salt $salt = random_bytes(32); - + // calculate verifier using this salt $verifier = $this->calculateSRP6Verifier($username, $password, $salt); // done - this is what you put in the account table! return array($salt, $verifier); } - + + public function strtoupper_az($str) { + //return preg_replace_callback('/[a-z]/',function($matches){return strtoupper($matches[0]);},$str); + return preg_replace_callback('/[a-z]/',function($matches){return chr(ord($matches[0])-32);},$str); + } + public function isOpen() { return ($this->conn != null); } - + // Close the database connection. public function close() { $this->conn = null; } - } ?> diff --git a/Trinity Account Creator/php/vars.php b/Trinity Account Creator/php/vars.php new file mode 100644 index 0000000..0a9124e --- /dev/null +++ b/Trinity Account Creator/php/vars.php @@ -0,0 +1,36 @@ + From 28e277c0db6a69cc9c88c859b253c1bccc12a557 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Wed, 2 Feb 2022 23:51:06 +0200 Subject: [PATCH 11/18] Update README.md --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 244a110..9e6d583 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,12 @@ Projects created for use with the TrinityCore World of Warcraft emulator: https://www.trinitycore.org/ # Requirements - gmp module is required to be enabled in PHP. On linux this means either `sudo apt install php-gmp` or editing the default php.ini and uncomment the `extension=gmp` line +[gmp](https://www.php.net/manual/en/book.gmp.php) module is required to be enabled in PHP. + * On Linux do `sudo apt install php-gmp` + * On Windows you should have `php_gmp.dll` in your extensions folder of your PHP installation + * Edit the default php.ini and uncomment the `extension=gmp` line. - pdo_mysql module is required to be enabled in PHP. On linux this means either `sudo apt install php-mysql` or editing the default php.ini and uncomment the `extension=pdo_mysql` line - - mbstring module is required to be enabled in PHP. On linux this means either `sudo apt install php-mbstring` or editing the default php.ini and uncomment the `extension=mbstring` line +[pdo_mysql](https://www.php.net/manual/en/ref.pdo-mysql.php) module is required to be enabled in PHP. + * On Linux do `sudo apt install php-mysql` + * On Windows you should have `php_pdo_mysql.dll` in your extensions folder of your PHP installation + * Edit the default php.ini and uncomment the `extension=pdo_mysql` line. From cf4a7b745895aed2858f66594b179425d83942bf Mon Sep 17 00:00:00 2001 From: anzz1 Date: Wed, 2 Feb 2022 23:58:26 +0200 Subject: [PATCH 12/18] . --- Trinity Account Creator/php/createAccount.php | 2 +- Trinity Account Creator/php/db.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index eb64aa2..e20b199 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -91,7 +91,7 @@ // Close connection to the database. $db->close(); - error_log("Account created: '" . $username . "' '". $email . "'"); + //error_log("Account created: '" . $username . "' '". $email . "'"); // Return successful to AJAX call. echo "0"; // Account created successfully! diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 161ea80..d428ff5 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -8,7 +8,7 @@ class db { private $host = "localhost"; // IP or hostname of your database server. private $port = "3306"; // Port of your database server. - private $username = "trinity"; // Database username. + private $username = "root"; // Database username. private $password = "trinity"; // Database password. private $dbname = "auth"; // Database name (i.e. "auth"). @@ -140,12 +140,12 @@ public function getRegistrationData($username, $password) } public function strtoupper_az($str) { - //return preg_replace_callback('/[a-z]/',function($matches){return strtoupper($matches[0]);},$str); - return preg_replace_callback('/[a-z]/',function($matches){return chr(ord($matches[0])-32);},$str); + //return preg_replace_callback('/[a-z]/',function($matches){return strtoupper($matches[0]);},$str); + return preg_replace_callback('/[a-z]/',function($matches){return chr(ord($matches[0])-32);},$str); } public function isOpen() { - return ($this->conn != null); + return ($this->conn != null); } // Close the database connection. From 3192db338598214d957879a10b557dad493a6a20 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Wed, 2 Feb 2022 23:59:32 +0200 Subject: [PATCH 13/18] root -> trinity --- Trinity Account Creator/php/db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index d428ff5..4685610 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -8,7 +8,7 @@ class db { private $host = "localhost"; // IP or hostname of your database server. private $port = "3306"; // Port of your database server. - private $username = "root"; // Database username. + private $username = "trinity"; // Database username. private $password = "trinity"; // Database password. private $dbname = "auth"; // Database name (i.e. "auth"). From a6be946b1c294d298d5d522399f5c14f3168c151 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Thu, 3 Feb 2022 06:51:35 +0200 Subject: [PATCH 14/18] Add PHP5 compatibility --- Trinity Account Creator/php/compat_random.php | 58 +++++++++++++++++++ Trinity Account Creator/php/createAccount.php | 9 ++- Trinity Account Creator/php/db.php | 13 ++++- Trinity Account Creator/php/vars.php | 19 ++++++ 4 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 Trinity Account Creator/php/compat_random.php diff --git a/Trinity Account Creator/php/compat_random.php b/Trinity Account Creator/php/compat_random.php new file mode 100644 index 0000000..b531f42 --- /dev/null +++ b/Trinity Account Creator/php/compat_random.php @@ -0,0 +1,58 @@ + diff --git a/Trinity Account Creator/php/createAccount.php b/Trinity Account Creator/php/createAccount.php index e20b199..04b9546 100644 --- a/Trinity Account Creator/php/createAccount.php +++ b/Trinity Account Creator/php/createAccount.php @@ -3,7 +3,14 @@ require_once(dirname(__FILE__) . '/vars.php'); require_once(dirname(__FILE__) . '/db.php'); - $db = new db(); + if (class_exists('db')) { + $db = new db(); + } + else { + echo "-1"; // Unknown error occured. + error_log("Error: Class db() could not be initialized."); + return; + } if (!$db->isOpen()) { echo "2"; // Connection failed diff --git a/Trinity Account Creator/php/db.php b/Trinity Account Creator/php/db.php index 4685610..44ee5d3 100644 --- a/Trinity Account Creator/php/db.php +++ b/Trinity Account Creator/php/db.php @@ -1,6 +1,7 @@ host;port=$this->port;dbname=$this->dbname;charset=utf8", $this->username, $this->password, - array( + $options = array( PDO::ATTR_TIMEOUT => 5, // Timeout is 5 seconds PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // Set PDO error mode to Exception. - )); + ); + if (version_compare(PHP_VERSION, "5.3.6", "<")) { + $connection = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname", $this->username, $this->password, $options); + $connection->exec('SET NAMES utf8'); + } + else { + $connection = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=utf8", $this->username, $this->password, $options); + } $this->conn = $connection; } diff --git a/Trinity Account Creator/php/vars.php b/Trinity Account Creator/php/vars.php index 0a9124e..8e14692 100644 --- a/Trinity Account Creator/php/vars.php +++ b/Trinity Account Creator/php/vars.php @@ -1,5 +1,24 @@ Date: Thu, 3 Feb 2022 07:24:26 +0200 Subject: [PATCH 15/18] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9e6d583..e18d3b9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Projects created for use with the TrinityCore World of Warcraft emulator: https://www.trinitycore.org/ # Requirements + +#### PHP Version >= 5.0.0 + [gmp](https://www.php.net/manual/en/book.gmp.php) module is required to be enabled in PHP. * On Linux do `sudo apt install php-gmp` * On Windows you should have `php_gmp.dll` in your extensions folder of your PHP installation From 19f67f1c7dda61f5bb54096eb63c6cf70e67a9fa Mon Sep 17 00:00:00 2001 From: anzz1 Date: Thu, 3 Feb 2022 10:17:31 +0200 Subject: [PATCH 16/18] Update compat_random * Add CAPICOM crypto provider for Windows --- Trinity Account Creator/php/compat_random.php | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/Trinity Account Creator/php/compat_random.php b/Trinity Account Creator/php/compat_random.php index b531f42..740a0b3 100644 --- a/Trinity Account Creator/php/compat_random.php +++ b/Trinity Account Creator/php/compat_random.php @@ -42,15 +42,38 @@ function random_bytes($b) { return ($rand !== false && bytelen($rand) == $b) ? $rand : null; } } + } elseif (class_exists('\\COM')) { + try { + $util = new COM('CAPICOM.Utilities.1'); + $method = array($util, 'GetRandom'); + if (is_callable($method)) { + function random_bytes($b) { + $util = new \COM('CAPICOM.Utilities.1'); + $rand = base64_decode($util->GetRandom($b,0)); + $rand = str_pad($rand, $b, chr(0)); + return ($rand !== false && bytelen($rand) == $b) ? $rand : null; + } + } + } catch (Exception $e) { } } if (!is_callable('random_bytes')) { - function random_bytes($b) { - $rand = ''; - for ($i = 1; $i <= $b; $i++) { - $rand .= chr(rand(0,255)); + if (is_callable('mt_rand')) { + function random_bytes($b) { + $rand = ''; + for ($i = 1; $i <= $b; $i++) { + $rand .= chr(mt_rand(0,255)); + } + return ($rand !== false && bytelen($rand) == $b) ? $rand : null; + } + } else { + function random_bytes($b) { + $rand = ''; + for ($i = 1; $i <= $b; $i++) { + $rand .= chr(rand(0,255)); + } + return ($rand !== false && bytelen($rand) == $b) ? $rand : null; } - return ($rand !== false && bytelen($rand) == $b) ? $rand : null; } } } From 5e34dfc93a650c1bb8c8928f301b7b1c22048481 Mon Sep 17 00:00:00 2001 From: anzz1 Date: Mon, 28 Feb 2022 19:14:25 +0200 Subject: [PATCH 17/18] Fix typo --- Trinity Account Creator/php/vars.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Trinity Account Creator/php/vars.php b/Trinity Account Creator/php/vars.php index 8e14692..9a1d6ae 100644 --- a/Trinity Account Creator/php/vars.php +++ b/Trinity Account Creator/php/vars.php @@ -46,7 +46,7 @@ function load_lib($n) { ini_set('iconv.input_encoding', ''); } if(ini_get('iconv.output_encoding')) { - ini_set('iconv.input_encoding', ''); + ini_set('iconv.output_encoding', ''); } if(ini_get('iconv.internal_encoding')) { ini_set('iconv.internal_encoding', ''); From 62a19ea09fc00ea0e6aaabc5c7b612e71e75bd0e Mon Sep 17 00:00:00 2001 From: anzz1 Date: Thu, 28 Aug 2025 16:21:47 +0300 Subject: [PATCH 18/18] Update compat_random.php --- Trinity Account Creator/php/compat_random.php | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/Trinity Account Creator/php/compat_random.php b/Trinity Account Creator/php/compat_random.php index 740a0b3..5e8a08b 100644 --- a/Trinity Account Creator/php/compat_random.php +++ b/Trinity Account Creator/php/compat_random.php @@ -9,15 +9,7 @@ function bytelen($str) { } if (!is_callable('random_bytes')) { - if (is_callable('gmp_random_bits')) { - function random_bytes($b) { - $rand = ''; - for ($i = 1; $i <= $b; $i++) { - $rand .= chr(gmp_intval(gmp_random_bits(8))); - } - return ($rand !== false && bytelen($rand) == $b) ? $rand : null; - } - } else if (is_callable('openssl_random_pseudo_bytes')) { + if (is_callable('openssl_random_pseudo_bytes')) { function random_bytes($b) { $rand = openssl_random_pseudo_bytes($b); return ($rand !== false && bytelen($rand) == $b) ? $rand : null; @@ -42,7 +34,7 @@ function random_bytes($b) { return ($rand !== false && bytelen($rand) == $b) ? $rand : null; } } - } elseif (class_exists('\\COM')) { + } else if (class_exists('\\COM')) { try { $util = new COM('CAPICOM.Utilities.1'); $method = array($util, 'GetRandom'); @@ -50,7 +42,7 @@ function random_bytes($b) { function random_bytes($b) { $util = new \COM('CAPICOM.Utilities.1'); $rand = base64_decode($util->GetRandom($b,0)); - $rand = str_pad($rand, $b, chr(0)); + $rand = ($rand !== false) ? str_pad($rand, $b, chr(0)) : false; return ($rand !== false && bytelen($rand) == $b) ? $rand : null; } } @@ -58,7 +50,15 @@ function random_bytes($b) { } if (!is_callable('random_bytes')) { - if (is_callable('mt_rand')) { + if (is_callable('gmp_random_bits')) { + function random_bytes($b) { + $rand = ''; + for ($i = 1; $i <= $b; $i++) { + $rand .= chr(gmp_intval(gmp_random_bits(8))); + } + return ($rand !== false && bytelen($rand) == $b) ? $rand : null; + } + } else if (is_callable('mt_rand')) { function random_bytes($b) { $rand = ''; for ($i = 1; $i <= $b; $i++) { @@ -78,4 +78,22 @@ function random_bytes($b) { } } +if (!is_callable('random_int')) { + if (is_callable('gmp_random_range')) { + function random_int($min, $max) { + return gmp_intval(gmp_random_range($min, $max)); + } + } elseif (is_callable('mt_rand')) { + function random_int($min, $max) { + mt_srand(random_bytes(3)); + return mt_rand($min, $max); + } + } elseif (is_callable('rand')) { + function random_int($min, $max) { + srand(random_bytes(3)); + return rand($min, $max); + } + } +} + ?>