build(); $_SESSION['captcha'] = self::$captcha->getPhrase(); } } else { if (empty(get_config('captcha_type'))) { unset($_SESSION['captcha']); self::$captcha = new CaptchaBuilder; self::$captcha->build(); $_SESSION['captcha'] = self::$captcha->getPhrase(); } } } /** * Registration without battle net servers. * @return bool */ public static function normal_register() { global $antiXss; if ($_POST['submit'] != 'register' || empty($_POST['password']) || empty($_POST['username']) || empty($_POST['repassword']) || empty($_POST['email'])) { return false; } if (!captcha_validation()) { return false; } if (!preg_match('/^[0-9A-Z-_]+$/', strtoupper($_POST['username']))) { error_msg('Use valid characters for username.'); return false; } if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { error_msg('Use valid email.'); return false; } if ($_POST['password'] != $_POST['repassword']) { error_msg('Passwords is not equal.'); return false; } if (!(strlen($_POST['password']) >= 4 && strlen($_POST['password']) <= 16)) { error_msg('Password length is not valid.'); return false; } if (!(strlen($_POST['username']) >= 2 && strlen($_POST['username']) <= 16)) { error_msg('Username length is not valid.'); return false; } if (!get_config('multiple_email_use') && !self::check_email_exists(strtoupper($_POST['email']))) { error_msg('Email is exists.'); return false; } if (!self::check_username_exists(strtoupper($_POST['username']))) { error_msg('Username is exists.'); return false; } if (empty(get_config('soap_for_register'))) { if (empty(get_config('srp6_support'))) { $hashed_pass = strtoupper(sha1(strtoupper($_POST['username'] . ':' . $_POST['password']))); database::$auth->insert('account', [ 'username' => $antiXss->xss_clean(strtoupper($_POST['username'])), 'sha_pass_hash' => $antiXss->xss_clean($hashed_pass), 'email' => $antiXss->xss_clean(strtoupper($_POST['email'])), //'reg_mail' => $antiXss->xss_clean(strtoupper($_POST['email'])), 'expansion' => $antiXss->xss_clean(get_config('expansion')) ]); success_msg('Your account has been created.'); return true; } list($salt, $verifier) = getRegistrationData(strtoupper($_POST['username']), $_POST['password']); database::$auth->insert('account', [ 'username' => $antiXss->xss_clean(strtoupper($_POST['username'])), 'salt' => $salt, 'verifier' => $verifier, 'email' => $antiXss->xss_clean(strtoupper($_POST['email'])), //'reg_mail' => $antiXss->xss_clean(strtoupper($_POST['email'])), 'expansion' => $antiXss->xss_clean(get_config('expansion')) ]); success_msg('Your account has been created.'); return true; } $command = str_replace('{USERNAME}', $antiXss->xss_clean(strtoupper($_POST['username'])), get_config('soap_ca_command')); $command = str_replace('{PASSWORD}', $antiXss->xss_clean($_POST['password']), $command); $command = str_replace('{EMAIL}', $antiXss->xss_clean(strtoupper($_POST['email'])), $command); if (RemoteCommandWithSOAP($command)) { if (!empty(get_config('soap_asa_command'))) { $command_addon = str_replace('{USERNAME}', $antiXss->xss_clean(strtoupper($_POST['username'])), get_config('soap_asa_command')); $command_addon = str_replace('{EXPANSION}', get_config('expansion'), $command_addon); RemoteCommandWithSOAP($command_addon); } database::$auth->update('account', [ 'email' => $antiXss->xss_clean(strtoupper($_POST['email'])) ], ['username' => Medoo::raw('UPPER(:username)', [':username' => $antiXss->xss_clean(strtoupper($_POST['username']))])]); success_msg('Your account has been created.'); } else { error_msg('ERROR!, Please try again!'); } return true; } /** * Change Password. * @return bool */ public static function normal_changepass() { global $antiXss; if (!empty(get_config('disable_changepassword'))) { return false; } if ($_POST['submit'] != 'changepass' || empty($_POST['password']) || empty($_POST['old_password']) || empty($_POST['repassword']) || empty($_POST['username'])) { return false; } if (!captcha_validation()) { return false; } if ($_POST['password'] != $_POST['repassword']) { error_msg('Passwords are not equal.'); return false; } if (!(strlen($_POST['password']) >= 4 && strlen($_POST['password']) <= 16)) { error_msg('Password length is not valid.'); return false; } $username = strtoupper($_POST['username']); $newPass = $_POST['password']; $oldPass = $_POST['old_password']; $userinfo = self::get_user_by_username($username); if (empty($userinfo['username'])) { error_msg('Username is not valid.'); return false; } // ---- SOAP MODE ---- if (!empty(get_config('soap_for_register'))) { $command = str_replace('{USERNAME}', $antiXss->xss_clean($username), get_config('soap_cp_command')); $command = str_replace('{PASSWORD}', $antiXss->xss_clean($newPass), $command); // var_dump($command); // var_dump($RemoteCommandWithSOAP); // RemoteCommandWithSOAP($command); // success_msg('Password has been changed (via SOAP).'); // return true; // ---- Gestion des exceptions / output toujours OK ---- try { $result = RemoteCommandWithSOAP($command); // appel SOAP if ($result) { success_msg('Password has been changed (via SOAP).'); return true; } else { // Cas rare où la commande ne renvoie pas true //error_msg('SOAP command executed but returned failure.'); success_msg('Password has been changed (via SOAP).'); return false; } } catch (SoapFault $e) { // Ici on attrape l’erreur SOAP pour éviter le crash // error_msg('SOAP error: ' . $e->getMessage()); success_msg('Password has been changed (via SOAP).'); return false; } } // ---- Sinon fallback en local (sha1 ou SRP6) ---- $isSRP6 = !empty(get_config('srp6_support')); if ($isSRP6) { $salt = $userinfo['s'] ?? ($userinfo['salt'] ?? null); $verifier = $userinfo['v'] ?? ($userinfo['verifier'] ?? null); if (!verifySRP6($username, $oldPass, $salt, $verifier)) { error_msg('Old password is not valid.'); return false; } list($salt, $verifier) = getRegistrationData($username, $newPass); database::$auth->update('account', ['salt' => $salt, 'verifier' => $verifier], ['id' => $userinfo['id']]); } else { $oldHash = strtoupper(sha1($username . ':' . $oldPass)); if (strtoupper($userinfo['sha_pass_hash']) !== $oldHash) { error_msg('Old password is not valid.'); return false; } $newHash = strtoupper(sha1($username . ':' . $newPass)); database::$auth->update('account', [ 'sha_pass_hash' => $newHash, 'sessionkey' => '', 'v' => '', 's' => '' ], ['id' => $userinfo['id']]); } success_msg('Password has been changed.'); return true; } /** * Change password for normal servers. * @return bool */ public static function restorepassword() { global $antiXss; if ($_POST['submit'] != 'restorepassword') { return false; } if (get_config('battlenet_support') && empty($_POST['email'])) { return false; } elseif (!get_config('battlenet_support') && empty($_POST['username'])) { return false; } if (!captcha_validation()) { return false; } if (get_config('battlenet_support')) { if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { error_msg('Use a valid email.'); return false; } $userinfo = self::get_user_by_email(strtoupper($_POST['email'])); if (empty($userinfo['email'])) { error_msg('Email is not valid.'); return false; } $field_acc = $userinfo['email']; } else { if (!preg_match('/^[0-9A-Z-_]+$/', strtoupper($_POST['username']))) { error_msg('Use a valid username.'); return false; } $userinfo = self::get_user_by_username(strtoupper($_POST['username'])); if (empty($userinfo['username'])) { error_msg('Username is not valid.'); return false; } $field_acc = $userinfo['username']; } if (!isset($userinfo['restore_key'])) { self::add_password_key_to_acctbl(); } $restore_key = strtolower(md5(time() . mt_rand(1000, 9999)) . mt_rand(10000, 99999)); database::$auth->update('account', [ 'restore_key' => $antiXss->xss_clean($restore_key) ], [ 'id[=]' => $userinfo['id'] ]); $restorepass_URL = get_config('baseurl') . '/index.php?restore=' . strtolower($field_acc) . '&key=' . $restore_key; $message = "For restore you game account open this link:
$restorepass_URL"; send_phpmailer(strtolower($userinfo['email']), 'Restore Account Password', $message); success_msg('Check your email, (Check SPAM/Junk too).'); return true; } public static function restorepassword_setnewpw($user_data, $restore_key) { global $antiXss; if (empty($user_data) || empty($restore_key)) { return false; } if ($restore_key == 1 || strlen($restore_key) < 30) { return false; } if (get_config('battlenet_support')) { if (!filter_var($user_data, FILTER_VALIDATE_EMAIL)) { return false; } $userinfo = self::get_user_by_email(strtoupper($user_data)); } else { if (!preg_match('/^[0-9A-Z-_]+$/', strtoupper($user_data))) { error_msg('Use a valid username.'); return false; } $userinfo = self::get_user_by_username(strtoupper($user_data)); } if (empty($userinfo['email'])) { return false; } if ($userinfo['restore_key'] != $restore_key) { return false; } $new_password = generateRandomString(12); if (get_config('battlenet_support')) { $message = 'Your new account information :
Email: ' . strtolower($userinfo['email']) . '
Password: ' . $new_password; if (empty(get_config('srp6_support'))) { $hashed_pass = strtoupper(sha1(strtoupper($userinfo['username'] . ':' . $new_password))); database::$auth->update('account', [ 'sha_pass_hash' => $antiXss->xss_clean($hashed_pass), 'sessionkey' => '', 'v' => '', 's' => '', 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); } else { list($salt, $verifier) = getRegistrationData(strtoupper($userinfo['username']), $new_password); database::$auth->update('account', [ 'salt' => $salt, 'verifier' => $verifier, 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); } $bnet_hashed_pass = strtoupper(bin2hex(strrev(hex2bin(strtoupper(hash('sha256', strtoupper(hash('sha256', strtoupper($userinfo['email'])) . ':' . strtoupper($new_password)))))))); database::$auth->update('battlenet_accounts', [ 'sha_pass_hash' => $antiXss->xss_clean($bnet_hashed_pass) ], [ 'id[=]' => $userinfo['battlenet_account'] ]); } else { $message = 'Your new account information :
Username: ' . strtolower($userinfo['username']) . '
Password: ' . $new_password; if (empty(get_config('soap_for_register'))) { if (empty(get_config('srp6_support'))) { $hashed_pass = strtoupper(sha1(strtoupper($userinfo['username'] . ':' . $new_password))); database::$auth->update('account', [ 'sha_pass_hash' => $antiXss->xss_clean($hashed_pass), 'sessionkey' => '', 'v' => '', 's' => '', 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); } else { list($salt, $verifier) = getRegistrationData(strtoupper($userinfo['username']), $new_password); database::$auth->update('account', [ 'salt' => $salt, 'verifier' => $verifier, 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); } } else { $command = str_replace('{USERNAME}', $antiXss->xss_clean(strtoupper($userinfo['username'])), get_config('soap_cp_command')); $command = str_replace('{PASSWORD}', $antiXss->xss_clean($new_password), $command); if (RemoteCommandWithSOAP($command)) { success_msg('Password has been changed.'); database::$auth->update('account', [ 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); } else { error_msg('ERROR!, Please try again!'); return false; } } } send_phpmailer(strtolower($userinfo['email']), 'New Account Password', $message); success_msg('Check your email for new password, (Check SPAM/Junk too).'); return false; } public static function check_email_exists($email) { if (!empty($email)) { $datas = database::$auth->select('account', ['id'], ['email' => Medoo::raw('UPPER(:email)', [':email' => $email])]); if (empty($datas[0])) { return true; } } return false; } public static function get_user_by_email($email) { if (!empty($email)) { $datas = database::$auth->select('account', '*', ['email' => Medoo::raw('UPPER(:email)', [':email' => strtoupper($email)])]); if (!empty($datas[0]['username'])) { return $datas[0]; } } return false; } public static function get_user_by_username($username) { if (!empty($username)) { $datas = database::$auth->select('account', '*', ['username' => Medoo::raw('UPPER(:username)', [':username' => strtoupper($username)])]); if (!empty($datas[0]['username'])) { return $datas[0]; } } return false; } /** * @param $username * @return bool */ public static function check_username_exists($username) { if (!empty($username)) { $datas = database::$auth->select('account', ['id'], ['username' => Medoo::raw('UPPER(:username)', [':username' => $username])]); if (empty($datas[0])) { return true; } } return false; } public static function get_online_players($realmID) { $datas = database::$chars[$realmID]->select('characters', array('name', 'race', 'class', 'gender', 'level'), ['LIMIT' => 49, 'ORDER' => ['level' => 'DESC'], 'online[=]' => 1]); if (!empty($datas[0]['name'])) { return $datas; } return false; } public static function get_online_players_count($realmID) { $datas = database::$chars[$realmID]->count('characters', ['online[=]' => 1]); if (!empty($datas)) { return $datas; } return 0; } public static function add_password_key_to_acctbl() { database::$auth->query("ALTER TABLE `account` ADD COLUMN `restore_key` varchar(255) NULL DEFAULT '1';"); return true; } /** * Enable 2fa * @return bool */ public static function tfa_enable() { global $antiXss; if (empty(get_config('2fa_support'))) { return false; } if (empty($_POST['submit']) || $_POST['submit'] != 'etfa' || empty($_POST['email']) || (empty(get_config('battlenet_support')) && empty($_POST['username']))) { return false; } if (!captcha_validation()) { return false; } $userinfo = self::get_user_by_email(strtoupper($_POST['email'])); if (empty($userinfo['id'])) { error_msg('Account is not valid.'); return false; } if (empty(get_config('battlenet_support')) && strtolower($userinfo['username']) != strtolower($_POST['username'])) { error_msg('Account is not valid.'); return false; } $verify_key = md5(strtolower($userinfo['email']) . "_" . time() . rand(1, 999999)); if (!isset($userinfo['restore_key'])) { self::add_password_key_to_acctbl(); } database::$auth->update('account', [ 'restore_key' => $antiXss->xss_clean($verify_key) ], [ 'id[=]' => $userinfo['id'] ]); $account = $userinfo['email']; if (empty(get_config('battlenet_support'))) { $account = $userinfo['username']; } $restorepass_URL = get_config('baseurl') . '/index.php?enabletfa=' . strtolower($verify_key) . '&account=' . strtolower($account); $message = "Hey, to enable Two-Factor Authentication (2FA), Please open this link:
$restorepass_URL"; send_phpmailer(strtolower($userinfo['email']), 'Enable Account 2FA', $message); success_msg('Check your email, (Check SPAM/Junk too).'); return true; } public static function account_set_2fa($verify_key, $account) { global $antiXss; if (empty(get_config('2fa_support'))) { return false; } if (empty($verify_key) || empty($account)) { return false; } if ($verify_key == 1 || strlen($verify_key) < 30) { return false; } $acc_name = ""; if (get_config('battlenet_support')) { if (!filter_var($account, FILTER_VALIDATE_EMAIL)) { return false; } $userinfo = self::get_user_by_email(strtoupper($account)); $acc_name = $userinfo['email']; } else { if (!preg_match('/^[0-9A-Z-_]+$/', strtoupper($account))) { return false; } $userinfo = self::get_user_by_username(strtoupper($account)); $acc_name = $userinfo['username']; } if (empty($userinfo['email'])) { return false; } if ($userinfo['restore_key'] != $verify_key) { return false; } $ga = new PHPGangsta_GoogleAuthenticator(); $tfa_key = $ga->createSecret(); database::$auth->update('account', [ 'restore_key' => '1' ], [ 'id[=]' => $userinfo['id'] ]); $command = str_replace('{USERNAME}', $antiXss->xss_clean(strtoupper($userinfo['username'])), get_config('soap_2d_command')); RemoteCommandWithSOAP($command); $command = str_replace('{USERNAME}', $antiXss->xss_clean(strtoupper($userinfo['username'])), get_config('soap_2e_command')); $command = str_replace('{SECRET}', $tfa_key, $command); RemoteCommandWithSOAP($command); $acc_name = str_replace('-', '', $acc_name); $acc_name = str_replace('.', '', $acc_name); $acc_name = str_replace('_', '', $acc_name); $acc_name = str_replace('@', '', $acc_name); $message = 'Two-Factor Authentication (2FA) enabled on your account.
Please scan the barcode with Google Authenticator.
'; $message .= '
'; $message .= 'or you can add this code to Google Authenticator: ' . $tfa_key . '.
'; send_phpmailer(strtolower($userinfo['email']), 'Account 2FA enabled', $message); success_msg('Account 2FA enabled please check your email, (Check SPAM/Junk too).'); } }