Move logic to the class

This commit is contained in:
Stanislas Dolcini 2018-10-03 21:38:30 +02:00
parent 38daa2aedd
commit b3f31f7d5f
3 changed files with 294 additions and 279 deletions

View file

@ -0,0 +1,292 @@
<?php
error_reporting(E_ERROR | E_PARSE);
set_error_handler('err_callback');
// For error handling, buffer all output
ob_start('ob_callback_r2login');
include_once 'config.php';
include_once 'login_translations.php';
include_once '../tools/nel_message.php';
include_once '../tools/domain_info.php';
include_once 'login_service_itf.php';
include_once '../ring/join_shard.php';
include_once './class/CWwwLog.php';
include_once './class/LoginCb.php';
class ConnectionHandler
{
private $db_Connection;
public function __construct()
{
}
public function connect($dbhost, $dbusername, $dbpassword, $dbname)
{
$this->db_Connection = new mysqli($dbhost, $dbusername, $dbpassword) or die(errorMsgBlock(3004, 'main', $DBHost, $DBUserName));
$this->db_Connection->select_db($dbname) or die(errorMsgBlock(3005, 'main', $dbname, $dbhost, $dbusername));
}
public function __destruct()
{
$db_Connection->close();
}
private function askSalt($login, $lang)
{
setMsgLanguage($lang);
$escaped_login = $mysqli->escape_string($login);
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if ($stmt = mysqli_prepare('SELECT TOP 1 Password FROM user WHERE Login=\'?\'')) {
$stmt->bind_param("s", $escaped_login);
$stmt->execute();
$stmt->bind_result($password) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if ($stmt->num_rows == 1 && $stmt->fetch()) {
$salt = get_salt($password);
} else {
die(errorMsgBlock(2001, $login, 'askSalt'));
}
$stmt->close();
}
return $salt;
}
private function Login($login, $password, $clientApplication, $cp, $submittedLang)
{
$res = false;
$domainId = -1;
// client sent is login info
if (!checkUserValidity($login, $password, $clientApplication, $cp, $id, $reason, $priv, $extended, $domainId, $submittedLang)) {
echo '0:' . $reason;
} else {
// retreive the domain info
$domainInfo = getDomainInfo($domainId);
// if we need to create missing ring info
if ($AutoCreateRingInfo) {
// check if the ring user exist, and create it if not
$ringDb = mysqli_connect($DBHost, $RingDBUserName, $RingDBPassword) or die(errorMsgBlock(3004, 'Ring', $DBHost, $RingDBUserName));
mysqli_select_db($ringDb, $domainInfo['ring_db_name']) or die(errorMsgBlock(3005, 'Ring', $domainInfo['ring_db_name'], $DBHost, $RingDBUserName));
$query = "SELECT user_id FROM ring_users where user_id = '" . $id . "'";
$result = mysqli_query($ringDb, $query) or die(errorMsgBlock(3006, $query, 'Ring', $domainInfo['ring_db_name'], $DBHost, $RingDBUserName, mysqli_error($ringDb)));
if (mysqli_num_rows($result) == 0) {
// no ring user record, build one
$login = mysqli_real_escape_string($ringDb, $_GET['login']);
$query = "INSERT INTO ring_users SET user_id = '$id', user_name = '$login', user_type='ut_pioneer'";
$result = mysqli_query($ringDb, $query) or die(errorMsgBlock(3006, $query, 'Ring', $domainInfo['ring_db_name'], $DBHost, $RingDBUserName, mysqli_error($ringDb)));
}
}
// store the web host for this domain
global $RingWebHost, $RingWebHostPHP;
$RingWebHost = $domainInfo['web_host'];
$RingWebHostPHP = $domainInfo['web_host_php'];
$LSaddr = explode(":", $domainInfo['login_address']);
// ask for a session cookie to the login service
$login = new LoginCb;
$res = "";
$login->connect($LSaddr[0], $LSaddr[1], $res);
$login->login($id, $_SERVER["REMOTE_ADDR"], $domainId);
// wait for the return message
if (!$login->waitCallback()) {
die(errorMsgBlock(3003));
}
//the rest of the process is done in the callback function
}
}
/**
* @param NelCommand
* the command you got from the client
*/
public function process_command($command)
{
switch ($command->cmd) {
case 'ask':
echo '1:' . askSalt($command->login, $command->submittedLang);
break;
case 'login-https':
$salt = askSalt($command->login, $command->submittedLang);
$generated_password = crypt($command->password, sprintf('$6$rounds=%d$%s$', 5000, $salt));
login($command->login, $generated_password, $command->clientApplication, $command->cp, $command->submittedLang);
break;
case 'login':
login($command->login, $command->password, $command->clientApplication, $command->cp, $command->submittedLang);
break;
default:
break;
}
}
/**
* @param string $login
* The user login.
* @todo: This should become the password.
* @param string $password
* The user's password.
* @param string $clientApplication
* @param ? $cp
* @param int $id
* @param string $id
* @param string $priv
* @param string $extended
* @param string $domainId
* @param string $lang
* @return true if the User is valid
*/
public function checkUserValidity($login, $password, $clientApplication, $cp, &$id, &$reason, &$priv, &$extended, &$domainId, $lang)
{
$res = false;
setMsgLanguage($lang);
$domainName = $mysqli->escape_string($clientApplication);
if ($stmt = $mysqli->prepare("SELECT TOP 1 domain_id FROM domain WHERE domain_name='?'")) {
$stmt->bind_param("s", $domainName);
$stmt->execute();
$stmt->bind_result($result) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$stmt->fetch();
if ($stmt->num_rows == 0) {
// unrecoverable error, we must giveup
$reason = errorMsg(3007, $domainName);
$mysqli->close();
return $res;
}
$stmt->close();
}
// retrieve the domain info
$domainInfo = getDomainInfo($domainId);
// convert the domain status enum into the privilege access set
$accessPriv = strtoupper(substr($domainInfo['status'], 3));
// now, retrieve the user infos
$login = $mysqli->escape_string($login);
$numrows = 0;
if ($stmt = mysqli_prepare("SELECT 1 FROM user WHERE Login='?'")) {
$stmt->bind_param("s", $login);
$stmt->execute();
$stmt->bind_result($result) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$stmt->fetch();
$numrows = $stmt->num_rows;
$stmt->close();
}
if ($numrows >= 0) {
$row = $mysqli->fetch_assoc();
$salt = get_salt($row["Password"]);
if (($cp && $row["Password"] == $password) || (!$cp && $row["Password"] == crypt($password, $salt))) {
// Store the real login (with correct case)
$_GET['login'] = $row['Login'];
// check if the user can use this application
$clientApplication = mysqli_real_escape_string($link, $clientApplication);
$query = "SELECT * FROM permission WHERE UId='" . $row["UId"] . "' AND DomainId='$domainId'";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if (mysqli_num_rows($result) == 0) {
if ($AcceptUnknownUser) {
// add default permission
$query = "INSERT INTO permission (UId, DomainId, ShardId, AccessPrivilege) VALUES ('" . $row["UId"] . "', '$domainId', -1, '$domainStatus')";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$reason = errorMsg(3010);
$res = false;
} else {
// no permission
$reason = errorMsg(3011, $clientApplication, $domainName);
$res = false;
}
} else {
// check that the access privilege for the domain
$permission = mysqli_fetch_assoc($result);
if (!strstr($permission['AccessPrivilege'], $accessPriv)) {
// no right to connect
if ($AcceptUnknownUser) {
// set an additionnal privilege for this player
$query = "UPDATE permission set AccessPrivilege='" . $permission['AccessPrivilege'] . ",$accessPriv' WHERE PermissionId=" . $permission['PermissionId'];
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$reason = errorMsg(3012, $accessPriv);
} else {
// no permission
$reason = errorMsg(3013, $clientApplication, $domainName, $accessPriv);
}
} else {
// // check if the user not already online
// if ($row["State"] != "Offline") {
// $reason = "$login is already online and ";
// // ask the LS to remove the client
// if (disconnectClient($row["ShardId"], $row["UId"], $tempres)) {
// $reason = $reason . "was just disconnected. Now you can retry the identification (error code 54)";
// $query = "update shard set NbPlayers=NbPlayers-1 where ShardId=" . $row["ShardId"];
// $result = mysqli_query($link, $query) or die("Can't execute the query: '$query' errno:" . mysqli_errno($link) . ": " . mysqli_error($link));
// $query = "update user set ShardId=-1, State='Offline' where UId=" . $row["UId"];
// $result = mysqli_query($link, $query) or die("Can't execute the query: '$query' errno:" . mysqli_errno($link) . ": " . mysqli_error($link));
// } else {
// $reason = $reason . "can't be disconnected: $tempres (error code 55)";
// }
// $res = false;
// } else {
$id = $row["UId"];
$priv = $row["Privilege"];
$extended = $row["ExtendedPrivilege"];
$res = true;
// }
}
}
} else {
$reason = errorMsg(2004, 'user');
}
}
$mysqli->close();
return $res;
}
public function errorMsgBlock($errNum = GENERIC_ERROR_NUM)
{
return '0:' . call_user_func_array('errorMsg', func_get_args());
}
/**
* Callback called on end of output buffering
*/
public function ob_callback_r2login($buffer)
{
// Log only in case of error or malformed result string
$blockHd = substr($buffer, 0, 2);
if ($blockHd != '1:') {
$logFile = new CWwwLog();
$logFile->logStr(str_replace("\n", '\n', $buffer));
}
return $buffer; // sent to output
}
// Callback called on error
public function err_callback($errno, $errmsg, $filename, $linenum, $vars)
{
$logFile = new CWwwLog();
$logFile->logStr("PHP ERROR/$errno $errmsg ($filename:$linenum)");
$logFile->logStr("PHP CALLSTACK/" . print_r(debug_backtrace(), true));
// Never die after an error
}
/**
* @param string
* the password to extract the salt from.
* @return string the salting prefix
*/
public function get_salt($password)
{
return $password[0] == '$' ? substr($password, 0, 19) : substr($password, 0, 2);
}
}

View file

@ -6,7 +6,7 @@ class NelCommand
public $password;
public $clientApplication;
public $cp;
public $lg;
public $submittedLang;
public function __construct($getParams)
{

View file

@ -1,19 +1,5 @@
<?php
error_reporting(E_ERROR | E_PARSE);
set_error_handler('err_callback');
// For error handling, buffer all output
ob_start('ob_callback_r2login');
include_once 'config.php';
include_once 'login_translations.php';
include_once '../tools/nel_message.php';
include_once '../tools/domain_info.php';
include_once 'login_service_itf.php';
include_once '../ring/join_shard.php';
include_once './class/CWwwLog.php';
include_once './class/LoginCb.php';
include_once './class/connection_handler.php';
include_once './class/nel_command.php';
@ -31,268 +17,5 @@ if (isset($_GET['dbg']) && ($_GET['dbg'] == 1)) {
$nel_command = new NelCommand($_GET);
$connection_handler = new ConnectionHandler();
$connection_handler->connect($DBHost, $DBUserName, $DBPassword, $DBName);
$connection_handler->process_command($nel_command);
// ----------------------------------------------------------------------------------------
// Functions
// ----------------------------------------------------------------------------------------
function get_salt($password)
{
return $password[0] == '$' ? substr($password, 0, 19) : substr($password, 0, 2);
}
// see errorMsg
// $mixedArgsx
function errorMsgBlock($errNum = GENERIC_ERROR_NUM)
{
return '0:' . call_user_func_array('errorMsg', func_get_args());
}
// Callback called on end of output buffering
function ob_callback_r2login($buffer)
{
// Log only in case of error or malformed result string
$blockHd = substr($buffer, 0, 2);
if ($blockHd != '1:') {
$logFile = new CWwwLog();
$logFile->logStr(str_replace("\n", '\n', $buffer));
}
return $buffer; // sent to output
}
// Callback called on error
function err_callback($errno, $errmsg, $filename, $linenum, $vars)
{
$logFile = new CWwwLog();
$logFile->logStr("PHP ERROR/$errno $errmsg ($filename:$linenum)");
$logFile->logStr("PHP CALLSTACK/" . print_r(debug_backtrace(), true));
// Never die after an error
}
/**
* @param string $login
* The user login.
* @todo: This should become the password.
* @param string $password
* The user's password.
* @param string $clientApplication
* @param ? $cp
* @param int $id
* @param string $id
* @param string $priv
* @param string $extended
* @param string $domainId
* @param string $lang
* @return true if the User is valid
*/
function checkUserValidity($login, $password, $clientApplication, $cp, &$id, &$reason, &$priv, &$extended, &$domainId, $lang)
{
global $DBHost;
global $DBUserName;
global $DBPassword;
global $DBName;
global $AcceptUnknownUser;
setMsgLanguage($lang);
$res = false;
$mysqli = new mysqli($DBHost, $DBUserName, $DBPassword) or die(errorMsgBlock(3004, 'main', $DBHost, $DBUserName));
$mysqli->select_db($DBName) or die(errorMsgBlock(3005, 'main', $DBName, $DBHost, $DBUserName));
$domainName = $mysqli->escape_string($clientApplication);
$numrows = 0;
if ($stmt = $mysqli->prepare("SELECT TOP 1 domain_id FROM domain WHERE domain_name='?'")) {
$stmt->bind_param("s", $domainName);
$stmt->execute();
$stmt->bind_result($result) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$stmt->fetch();
$numrows = $stmt->num_rows;
$stmt->close();
}
if ($numrows == 0) {
// unrecoverable error, we must giveup
$reason = errorMsg(3007, $domainName);
$mysqli->close();
return false;
}
// retrieve the domain info
$domainInfo = getDomainInfo($domainId);
// convert the domain status enum into the privilege access set
$accessPriv = strtoupper(substr($domainInfo['status'], 3));
// now, retrieve the user infos
$login = $mysqli->escape_string($login);
$numrows = 0;
if ($stmt = mysqli_prepare("SELECT 1 FROM user WHERE Login='?'")) {
$stmt->bind_param("s", $login);
$stmt->execute();
$stmt->bind_result($result) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$stmt->fetch();
$numrows = $stmt->num_rows;
$stmt->close();
}
if ($numrows == 0) {
if ($AcceptUnknownUser) {
// login doesn't exist, create it
$escaped_password = $mysqli->escape_string($password);
$query = "INSERT INTO user (Login, Password) VALUES ('$login', '$escaped_password')";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
// get the user to have his UId
$query = "SELECT * FROM user WHERE Login='$login'";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if (mysqli_num_rows($result) == 1) {
$reason = errorMsg(3008, $login);
$row = mysqli_fetch_assoc($result);
$id = $row["UId"];
$priv = $row["Privilege"];
$extended = $row["ExtendedPrivilege"];
// add the default permission
$query = "INSERT INTO permission (UId, DomainId, AccessPrivilege) VALUES ('$id', '$domainId', '$accessPriv')";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$res = false;
} else {
$reason = errorMsg(3009, $login);
$res = false;
}
} else {
$reason = errorMsg(2001, $login, 'checkUserValidity');
}
} else {
$row = $mysqli->fetch_assoc();
$salt = get_salt($row["Password"]);
if (($cp && $row["Password"] == $password) || (!$cp && $row["Password"] == crypt($password, $salt))) {
// Store the real login (with correct case)
$_GET['login'] = $row['Login'];
// check if the user can use this application
$clientApplication = mysqli_real_escape_string($link, $clientApplication);
$query = "SELECT * FROM permission WHERE UId='" . $row["UId"] . "' AND DomainId='$domainId'";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if (mysqli_num_rows($result) == 0) {
if ($AcceptUnknownUser) {
// add default permission
$query = "INSERT INTO permission (UId, DomainId, ShardId, AccessPrivilege) VALUES ('" . $row["UId"] . "', '$domainId', -1, '$domainStatus')";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$reason = errorMsg(3010);
$res = false;
} else {
// no permission
$reason = errorMsg(3011, $clientApplication, $domainName);
$res = false;
}
} else {
// check that the access privilege for the domain
$permission = mysqli_fetch_assoc($result);
if (!strstr($permission['AccessPrivilege'], $accessPriv)) {
// no right to connect
if ($AcceptUnknownUser) {
// set an additionnal privilege for this player
$query = "UPDATE permission set AccessPrivilege='" . $permission['AccessPrivilege'] . ",$accessPriv' WHERE PermissionId=" . $permission['PermissionId'];
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
$reason = errorMsg(3012, $accessPriv);
} else {
// no permission
$reason = errorMsg(3013, $clientApplication, $domainName, $accessPriv);
}
} else {
// // check if the user not already online
// if ($row["State"] != "Offline") {
// $reason = "$login is already online and ";
// // ask the LS to remove the client
// if (disconnectClient($row["ShardId"], $row["UId"], $tempres)) {
// $reason = $reason . "was just disconnected. Now you can retry the identification (error code 54)";
// $query = "update shard set NbPlayers=NbPlayers-1 where ShardId=" . $row["ShardId"];
// $result = mysqli_query($link, $query) or die("Can't execute the query: '$query' errno:" . mysqli_errno($link) . ": " . mysqli_error($link));
// $query = "update user set ShardId=-1, State='Offline' where UId=" . $row["UId"];
// $result = mysqli_query($link, $query) or die("Can't execute the query: '$query' errno:" . mysqli_errno($link) . ": " . mysqli_error($link));
// } else {
// $reason = $reason . "can't be disconnected: $tempres (error code 55)";
// }
// $res = false;
// } else {
$id = $row["UId"];
$priv = $row["Privilege"];
$extended = $row["ExtendedPrivilege"];
$res = true;
// }
}
}
} else {
$reason = errorMsg(2004, 'user');
}
}
$mysqli->close();
return $res;
}
function askSalt($login, $lang)
{
global $PHP_SELF;
global $DBHost, $DBUserName, $DBPassword, $DBName;
global $AcceptUnknownUser;
setMsgLanguage($lang);
$link = mysqli_connect($DBHost, $DBUserName, $DBPassword) or die(errorMsgBlock(3004, 'main', $DBHost, $DBUserName));
mysqli_select_db($link, $DBName) or die(errorMsgBlock(3005, 'main', $DBName, $DBHost, $DBUserName));
$login = mysqli_real_escape_string($link, $login);
$query = "SELECT Password FROM user WHERE Login='$login'";
$result = mysqli_query($link, $query) or die(errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if (mysqli_num_rows($result) != 1) {
if ($AcceptUnknownUser) {
// just accept the client and return a default salk
echo "1:AA";
die;
} else {
die(errorMsgBlock(2001, $login, 'askSalt'));
// Check if this is not an unconfirmed account
/*$query = "SELECT GamePassword, Language FROM signup_data WHERE login='$login'";
$result = mysqli_query($link, $query) or die (errorMsgBlock(3006, $query, 'main', $DBName, $DBHost, $DBUserName, mysqli_error($link)));
if (mysqli_num_rows($result) == 0)
{
// no user record, reject it
die (errorMsgBlock(2001, $login, 'askSalt'));
}
else if (mysqli_num_rows($result) == 1)
{
// one unconfirmed record, let the client send the encrypted password to get the corresponding email address
$row = mysqli_fetch_assoc($result);
$salt = substr($row['GamePassword'], 0, 2);
}
else
{
if ($lang == 'unknown')
{
// several matching records => display a multi-language message now
$languages = array();
while ($row = mysqli_fetch_assoc($result))
{
$languages[$row['Language']] = true;
}
setMsgLanguage(array_keys($languages));
}
die (errorMsgBlock(2003));
}*/
}
} else {
$res_array = mysqli_fetch_assoc($result);
$salt = get_salt($res_array['Password']);
}
mysqli_close($link);
return $salt;
}