Использование базового TOTP через мобильное приложение вместо существующей реализации второго пароля на javascript.
This commit is contained in:
parent
85b74015b7
commit
244e081014
69
_incl_data/class/Core/TOTP.php
Normal file
69
_incl_data/class/Core/TOTP.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Core;
|
||||||
|
|
||||||
|
readonly class TOTP
|
||||||
|
{
|
||||||
|
private const BASE32CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; // RFC 4648 Base32
|
||||||
|
|
||||||
|
public function __construct(private string $secret)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function otpSecret($uniqueString, $length = 20): string
|
||||||
|
{
|
||||||
|
// Уникальная строка + текущее время в микросекундах
|
||||||
|
$seed = $uniqueString . microtime(true);
|
||||||
|
|
||||||
|
// Хэшируем сид для более случайного распределения
|
||||||
|
$seed = hash('sha256', $seed);
|
||||||
|
|
||||||
|
$secret = '';
|
||||||
|
$max = strlen(self::BASE32CHARS) - 1;
|
||||||
|
|
||||||
|
// Генерируем случайную строку нужной длины
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$index = hexdec(substr($seed, $i, 2)) % $max; // Получаем индекс символа из хэшированного сида
|
||||||
|
$secret .= self::BASE32CHARS[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generate(int $digits = 6, int $timeStep = 30): string
|
||||||
|
{
|
||||||
|
$time = floor(time() / $timeStep);
|
||||||
|
$secretKey = $this->base32_decode($this->secret);
|
||||||
|
$binaryTime = pack('N*', 0) . pack('N*', $time);
|
||||||
|
$hash = hash_hmac('sha1', $binaryTime, $secretKey, true);
|
||||||
|
$offset = ord($hash[strlen($hash) - 1]) & 0x0F;
|
||||||
|
$otp = (
|
||||||
|
((ord($hash[$offset]) & 0x7F) << 24) |
|
||||||
|
((ord($hash[$offset + 1]) & 0xFF) << 16) |
|
||||||
|
((ord($hash[$offset + 2]) & 0xFF) << 8) |
|
||||||
|
(ord($hash[$offset + 3]) & 0xFF)
|
||||||
|
) % 10 ** $digits;
|
||||||
|
return str_pad((string)$otp, $digits, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function base32_decode(string $input): string
|
||||||
|
{
|
||||||
|
$base32charsFlipped = array_flip(str_split(self::BASE32CHARS));
|
||||||
|
$output = '';
|
||||||
|
$v = 0;
|
||||||
|
$vbits = 0;
|
||||||
|
|
||||||
|
for ($i = 0, $j = strlen($input); $i < $j; $i++) {
|
||||||
|
$v <<= 5;
|
||||||
|
if ($input[$i] == '=') continue;
|
||||||
|
$v += $base32charsFlipped[$input[$i]];
|
||||||
|
$vbits += 5;
|
||||||
|
|
||||||
|
if ($vbits >= 8) {
|
||||||
|
$vbits -= 8;
|
||||||
|
$output .= chr(($v & (0xFF << $vbits)) >> $vbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
@ -6,30 +6,24 @@ use Core\Config;
|
|||||||
use Core\Db;
|
use Core\Db;
|
||||||
use Helper\Mail;
|
use Helper\Mail;
|
||||||
use PassGen;
|
use PassGen;
|
||||||
use UserIp;
|
|
||||||
|
|
||||||
class Confirmation
|
class Confirmation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Для однотипных писем с подтверждением.
|
* Для однотипных писем с подтверждением.
|
||||||
* @param array $userinfo Данные из (User)->info.
|
* @param array $userinfo Данные из (User)->info.
|
||||||
* @param mixed $value Новое значение
|
* @param string $value Новое значение
|
||||||
* @param ?int $code Проверочный код
|
* @param ?int $code Проверочный код
|
||||||
* @param string $type Тип меняемого значения. С маленькой буквы, именительный падеж.
|
* @param string $type Тип меняемого значения. С маленькой буквы, именительный падеж.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function byEmail(array $userinfo, string $type, $value, ?int $code = null)
|
public static function byEmail(array $userinfo, string $type, string $value, ?int $code = null): void
|
||||||
{
|
{
|
||||||
if ($type === 'pass2' && is_null($code)) {
|
|
||||||
self::pass2ByEmailCustom($userinfo, $value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$ip = UserIp::get();
|
$ip = UserIp::get();
|
||||||
$date = date('d.m.y H:i');
|
$date = date('d.m.y H:i');
|
||||||
$https = Config::get('https');
|
$https = Config::get('https');
|
||||||
$support = Config::get('support');
|
$support = Config::get('support');
|
||||||
$activationLink = 'https://' . $userinfo['city'] . Config::get('host') .
|
$activationLink = Config::get('https') . "/confirm.php?id={$userinfo['id']}&code=$code";
|
||||||
"/confirm.php?id={$userinfo['id']}&code=$code";
|
|
||||||
$fulllogin = $userinfo['login'] . "[{$userinfo['level']}]";
|
$fulllogin = $userinfo['login'] . "[{$userinfo['level']}]";
|
||||||
Mail::send(
|
Mail::send(
|
||||||
$userinfo['mail'],
|
$userinfo['mail'],
|
||||||
@ -55,31 +49,7 @@ class Confirmation
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function pass2ByEmailCustom(array $userinfo, string $pass2)
|
public static function userRegistrationCodeByEmail(string $email, string $login): void
|
||||||
{
|
|
||||||
|
|
||||||
$ip = UserIp::get();
|
|
||||||
$fulllogin = $userinfo['login'] . "[{$userinfo['level']}]";
|
|
||||||
Mail::send(
|
|
||||||
$userinfo['mail'],
|
|
||||||
<<<HTML
|
|
||||||
<html lang="ru">
|
|
||||||
<head><title>Второй пароль от персонажа $fulllogin.</title></head>
|
|
||||||
<body>
|
|
||||||
Вами, с IP адреса - $ip, был установлен второй пароль в игре Бойцовский Клуб.<br>
|
|
||||||
Если это были не Вы, свяжитесь с администрацией сайта.<br><br>
|
|
||||||
------------------------------------------------------------------<br>
|
|
||||||
Ваш логин | {$userinfo['login']}<br>
|
|
||||||
Второй пароль | ' . $pass2 . '<br>
|
|
||||||
------------------------------------------------------------------<br>
|
|
||||||
<br><br>Желаем Вам приятной игры.<br><br><i>Администрация</i>
|
|
||||||
</body>
|
|
||||||
HTML,
|
|
||||||
"Второй пароль от персонажа $fulllogin"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function userRegistrationCodeByEmail(string $email, string $login)
|
|
||||||
{
|
{
|
||||||
$code = PassGen::intCode(4);
|
$code = PassGen::intCode(4);
|
||||||
Db::sql('insert into secure_code (email, code, time) values (?,?,unix_timestamp())', [$email, $code]);
|
Db::sql('insert into secure_code (email, code, time) values (?,?,unix_timestamp())', [$email, $code]);
|
||||||
|
@ -57,28 +57,5 @@ class Password
|
|||||||
}
|
}
|
||||||
return $this->info['pass'];
|
return $this->info['pass'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeSecond(?int $passLength): array
|
|
||||||
{
|
|
||||||
if (in_array($passLength, [4, 6, 8])) {
|
|
||||||
$query = 'update users set pass2 = ? where id = ?';
|
|
||||||
$pass2 = PassGen::intCode($passLength);
|
|
||||||
$args = [
|
|
||||||
password_hash($pass2, PASSWORD_DEFAULT),
|
|
||||||
$this->info['id'],
|
|
||||||
];
|
|
||||||
Confirmation::byEmail($this->info, 'pass2', $pass2);
|
|
||||||
$hash = $args[0];
|
|
||||||
} else {
|
|
||||||
$query = 'update users set pass2 = default where id = ?';
|
|
||||||
$args = [$this->info['id']];
|
|
||||||
}
|
|
||||||
|
|
||||||
Db::sql($query, $args);
|
|
||||||
return [
|
|
||||||
'pass2' => $pass2 ?? '',
|
|
||||||
'hash' => $hash ?? null,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
430
enter.php
430
enter.php
@ -3,6 +3,8 @@
|
|||||||
use Core\Config;
|
use Core\Config;
|
||||||
use Core\Database;
|
use Core\Database;
|
||||||
use Core\Db;
|
use Core\Db;
|
||||||
|
use Core\TOTP;
|
||||||
|
use JetBrains\PhpStorm\NoReturn;
|
||||||
use User\Password;
|
use User\Password;
|
||||||
use User\UserIp;
|
use User\UserIp;
|
||||||
|
|
||||||
@ -15,43 +17,36 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . '_incl_data/autoload.php';
|
|||||||
Database::init();
|
Database::init();
|
||||||
|
|
||||||
define('IP', UserIp::get());
|
define('IP', UserIp::get());
|
||||||
|
|
||||||
$chat = new Chat();
|
$chat = new Chat();
|
||||||
|
$login = $_SESSION['login'] ?? '';
|
||||||
|
$password = '';
|
||||||
|
$otp = '';
|
||||||
|
|
||||||
if (isset($_GET['login'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$_POST['login'] = $_GET['login'];
|
if (isset($_POST['login'])) {
|
||||||
$_POST['pass'] = $_GET['pass'];
|
$login = $_POST['login'];
|
||||||
$_POST['code'] = $_GET['code'];
|
}
|
||||||
|
if (isset($_POST['password'])) {
|
||||||
|
$password = $_POST['password'];
|
||||||
|
}
|
||||||
|
if (isset($_POST['otp'])) {
|
||||||
|
$otp = $_POST['otp'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_POST['psw'])) {
|
#[NoReturn] function error($e): void
|
||||||
$_POST['pass'] = $_POST['psw'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_SESSION['login'])) {
|
|
||||||
$_POST['login'] = $_SESSION['login'];
|
|
||||||
$_POST['pass'] = $_SESSION['pass'];
|
|
||||||
}
|
|
||||||
|
|
||||||
function error($e)
|
|
||||||
{
|
{
|
||||||
die(
|
$returnLink = Config::get('https');
|
||||||
'
|
$html = <<<HTML
|
||||||
<link rel="stylesheet" href="error.css">
|
<link rel="stylesheet" href="error.css">
|
||||||
<div class="text-wrapper">
|
<div class="text-wrapper">
|
||||||
<div class="title" data-content="Ошибка">
|
<div class="title" data-content="Ошибка">Ошибка!!</div>
|
||||||
Ошибка!!
|
<div class="subtitle">$e</div>
|
||||||
|
<div class="buttons"><a class="button" href="$returnLink">Вернуться назад</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
HTML;
|
||||||
<div class="subtitle">
|
exit($html);
|
||||||
' . $e . '
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buttons">
|
|
||||||
<a class="button" href="' . Config::get('https') . '">Вернуться назад</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$u = Db::getRow(
|
$u = Db::getRow(
|
||||||
@ -60,259 +55,154 @@ $u = Db::getRow(
|
|||||||
users.login,
|
users.login,
|
||||||
auth,
|
auth,
|
||||||
pass,
|
pass,
|
||||||
pass2,
|
totp,
|
||||||
users.city,
|
|
||||||
users.ip,
|
users.ip,
|
||||||
ipreg,
|
ipreg,
|
||||||
admin,
|
admin,
|
||||||
online,
|
online,
|
||||||
banned,
|
banned,
|
||||||
host_reg,
|
|
||||||
timereg,
|
|
||||||
securetime,
|
|
||||||
users_delo.text as block_reason
|
users_delo.text as block_reason
|
||||||
from users
|
from users
|
||||||
left join users_delo on users.id = users_delo.uid
|
left join users_delo on users.id = users_delo.uid
|
||||||
where users.login = ?',
|
where users.login = ?',
|
||||||
[$_POST['login']]
|
[$login]
|
||||||
);
|
);
|
||||||
$auth = Db::getValue('select id from logs_auth where uid = ? and ip = ?', [$u['id'], IP]);
|
|
||||||
|
|
||||||
if (!isset($u['id'])) {
|
if (empty($_SESSION['login'])) {
|
||||||
error('Логин "' . $_POST['login'] . '" не найден в базе.');
|
if (!isset($u['id'])) {
|
||||||
} elseif ($u['banned'] > 0) {
|
error('Логин "' . $login . '" не найден в базе.');
|
||||||
$blockstr = "Персонаж <b>{$u['login']}</b> заблокирован.";
|
} elseif ($u['banned'] > 0) {
|
||||||
$blockstr .= $u['block_reason'] ? "Причина блокировки: {$u['block_reason']}<br><br>" : '<br><br>';
|
$blockstr = "Персонаж <b>{$u['login']}</b> заблокирован.";
|
||||||
error($blockstr);
|
$blockstr .= $u['block_reason'] ? "Причина блокировки: {$u['block_reason']}<br><br>" : '<br><br>';
|
||||||
} elseif (!Password::isGood($_POST['pass'], $u['pass'], $u['login'])) {
|
error($blockstr);
|
||||||
error("Неверный пароль к персонажу {$u['login']}.");
|
} elseif (!Password::isGood($password, $u['pass'], $u['login'])) {
|
||||||
Db::sql(
|
|
||||||
'insert into logs_auth (uid, ip, browser, type, time) values (?,?,?,3,unix_timestamp())',
|
|
||||||
[$u['id'], IP, $_SERVER['HTTP_USER_AGENT']]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//Второй пароль
|
|
||||||
if (!empty($u['pass2'])) {
|
|
||||||
$_SESSION['login'] = $_POST['login'];
|
|
||||||
$_SESSION['pass'] = $_POST['pass'];
|
|
||||||
$good2 = false;
|
|
||||||
$koko = '';
|
|
||||||
if (password_verify($_POST['code'], $u['pass2'])) {
|
|
||||||
$good2 = true;
|
|
||||||
unset($_SESSION['login'], $_SESSION['pass']);
|
|
||||||
} else {
|
|
||||||
if (isset($_POST['code'])) {
|
|
||||||
$koko = 'Неверный второй пароль<br>';
|
|
||||||
}
|
|
||||||
setcookie('login', '', time() - 60 * 60 * 24, '', Config::get('host'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($koko) {
|
|
||||||
$koko = '<b style="color: red">' . $koko . '</b>';
|
|
||||||
}
|
|
||||||
if (!$good2) {
|
|
||||||
?>
|
|
||||||
<!Doctype html>
|
|
||||||
<HTML lang="ru">
|
|
||||||
<HEAD>
|
|
||||||
<link rel=stylesheet type="text/css">
|
|
||||||
|
|
||||||
<meta name="msapplication-config" content="browserconfig.xml"/>
|
|
||||||
<TITLE>Второй пароль</TITLE>
|
|
||||||
</HEAD>
|
|
||||||
<body style="background-color: #dfdfde;">
|
|
||||||
<H3>Запрос второго пароля к персонажу.</H3>
|
|
||||||
<?= $koko ?>
|
|
||||||
<div style="text-align: center">
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<img id="pass" onClick="" width="295" src="i/pin/e0.png" alt="pass">
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<img id="p1" onClick="" src="" alt="p1">
|
|
||||||
<img id="p2" onClick="" src="" alt="p2">
|
|
||||||
<img id="p3" onClick="" src="" alt="p3">
|
|
||||||
<br>
|
|
||||||
<img id="p4" onClick="" src="" alt="p4">
|
|
||||||
<img id="p5" onClick="" src="" alt="p5">
|
|
||||||
<img id="p6" onClick="" src="" alt="p6">
|
|
||||||
<br>
|
|
||||||
<img id="p7" onClick="" src="" alt="p7">
|
|
||||||
<img id="p8" onClick="" src="" alt="p8">
|
|
||||||
<img id="p9" onClick="" src="" alt="p9">
|
|
||||||
<br>
|
|
||||||
<img onClick="keypush(12);" src="i/pin/12.png" alt="back">
|
|
||||||
<img id="p0" name="image" onClick="" src="" alt="nan">
|
|
||||||
<img onClick="keypush(11);" src="i/pin/11.png" alt="ok">
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</BODY>
|
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var dopass = '';
|
|
||||||
var tdopass = '';
|
|
||||||
var lenth = 0;
|
|
||||||
randomp();
|
|
||||||
|
|
||||||
function randomp() {
|
|
||||||
var ss = [];
|
|
||||||
var n = 0;
|
|
||||||
while (n < 10) {
|
|
||||||
ss[n] = n;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
var k = 0;
|
|
||||||
var m = 0;
|
|
||||||
var tmpp = 0;
|
|
||||||
while (i < 10) {
|
|
||||||
k = getRandomInt(10);
|
|
||||||
m = getRandomInt(10);
|
|
||||||
if (k != m) {
|
|
||||||
tmpp = ss[k];
|
|
||||||
ss[k] = ss[m];
|
|
||||||
ss[m] = tmpp;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n = 10;
|
|
||||||
while (n > -1) {
|
|
||||||
n = n - 1;
|
|
||||||
document.getElementById('p' + n).setAttribute("src", "i/pin/" + ss[n] + ".png");
|
|
||||||
document.getElementById('p' + n).setAttribute("onClick", "keypush(" + ss[n] + ");");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRandomInt(max) {
|
|
||||||
return Math.floor(Math.random() * Math.floor(max));
|
|
||||||
}
|
|
||||||
|
|
||||||
function keypush(n) {
|
|
||||||
if (n == 12) {
|
|
||||||
|
|
||||||
if (lenth > 0) {
|
|
||||||
|
|
||||||
dopass = '';
|
|
||||||
|
|
||||||
lenth = 0;
|
|
||||||
document.getElementById('pass').setAttribute("src", "i/pin/e" + lenth + ".png");
|
|
||||||
}
|
|
||||||
} else if (n == 11) {
|
|
||||||
|
|
||||||
var $_POST = <?= json_encode($_POST); ?>;
|
|
||||||
window.location.replace("/enter.php?code=" + dopass + "&login=" + $_POST['login'] + "&pass=" + $_POST['pass']);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (lenth < 8) {
|
|
||||||
dopass = dopass + '' + n;
|
|
||||||
lenth++;
|
|
||||||
document.getElementById('pass').setAttribute("src", "i/pin/e" + lenth + ".png");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</HTML>
|
|
||||||
<?php
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Db::getValue('select count(*) from stats where id = ?', [$u['id']])) {
|
|
||||||
Db::sql('insert into stats (id, stats) values (?,?)', [$u['id'], 's1=3|s2=3|s3=3|s4=3|rinv=40|m9=5|m6=10']);
|
|
||||||
}
|
|
||||||
if (!Db::getValue('select count(*) from online where uid = ?', [$u['id']])) {
|
|
||||||
Db::sql('insert into online (uid, timeStart) values (?,unix_timestamp())', [$u['id']]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_COOKIE['login'])) {
|
|
||||||
setcookie('login', '', time() - 60 * 60 * 24, '', Config::get('host'));
|
|
||||||
}
|
|
||||||
|
|
||||||
//мульты
|
|
||||||
if ($u['admin'] === 0) {
|
|
||||||
$ipm1 = Db::getValue(
|
|
||||||
'select ip from logs_auth where uid = ? and ip != ? order by id limit 1',
|
|
||||||
[$u['id'], $u['ip']]
|
|
||||||
);
|
|
||||||
$ppl = Db::getRows(
|
|
||||||
'select * from logs_auth where ip != ? and (ip = ? or ip = ? or ip = ? or ip = ? or ip = ?)',
|
|
||||||
['', $u['ip'], $ipm1, $u['ipreg'], IP, $_COOKIE['ip']]
|
|
||||||
);
|
|
||||||
foreach ($ppl as $item) {
|
|
||||||
$ml = Db::getValue(
|
|
||||||
'select id from mults where (uid = ? and uid2 = ?) or (uid = ? and uid2 = ?) limit 1',
|
|
||||||
[$item['uid'], $u['id'], $u['id'], $item['uid']]
|
|
||||||
);
|
|
||||||
if (!$ml && $item['ip'] !== '' && $item['ip'] !== '127.0.0.1') {
|
|
||||||
Db::sql('insert into mults (uid, uid2, ip) VALUES (?,?,?)', [$u['id'], $item['uid'], $item['ip']]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_COOKIE['ip']) && $_COOKIE['ip'] != IP) {
|
|
||||||
Db::sql(
|
Db::sql(
|
||||||
'insert into logs_auth (uid, ip, browser, type, time) VALUES (?,?,?,1,unix_timestamp())',
|
'insert into logs_auth (uid, ip, browser, type, time) values (?,?,?,3,unix_timestamp())',
|
||||||
[$u['id'], $_COOKIE['ip'], $_SERVER['HTTP_USER_AGENT']]
|
[$u['id'], IP, $_SERVER['HTTP_USER_AGENT']]
|
||||||
);
|
);
|
||||||
|
error("Неверный пароль к персонажу {$u['login']}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
setcookie('login', $_POST['login'] ?? '', time() + 60 * 60 * 24 * 7, '', Config::get('host'));
|
$_SESSION['login'] = $u['login'];
|
||||||
setcookie('ip', IP, time() + 60 * 60 * 24 * 150, '');
|
if (!empty($u['totp'])) {
|
||||||
|
$_SESSION['totp'] = new TOTP($u['totp']);
|
||||||
if ($u['online'] < time() - 520) {
|
|
||||||
$sp = Db::getRows('select room, city, login from users where online > unix_timestamp() - 600 and id in (select user from friends where friend = ?)', [$u['id']]);
|
|
||||||
foreach ($sp as $usr) {
|
|
||||||
$chatDto = new ChatMessage();
|
|
||||||
$chatDto->setRoom($usr['room']);
|
|
||||||
$chatDto->setCity($usr['city']);
|
|
||||||
$chatDto->setTo($usr['login']);
|
|
||||||
$chatDto->setText('Вас приветствует: <b>' . $u['login'] . '</b>.');
|
|
||||||
$chatDto->setType(6);
|
|
||||||
$chat->sendMsg($chatDto);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$apu = '';
|
|
||||||
Db::sql('update dump set ver = 1, upd = 2 where uid = ?', [$u['id']]);
|
|
||||||
|
|
||||||
if (
|
|
||||||
$u['auth'] != md5($u['login'] . 'AUTH' . IP) ||
|
|
||||||
$_COOKIE['auth'] != md5($u['login'] . 'AUTH' . IP) ||
|
|
||||||
$u['auth'] == '' || $u['auth'] == '0'
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
$u['auth'] != '' &&
|
|
||||||
$u['auth'] != '0' &&
|
|
||||||
$u['ip'] != IP
|
|
||||||
) {
|
|
||||||
$cmsg = new ChatMessage();
|
|
||||||
$cmsg->setTo($u['login']);
|
|
||||||
$cmsg->setText('В предыдущий раз этим персонажем заходили с другого компьютера ' . date('d.m.Y H:i', $u['online']) . "(Предыдущий ip: %{$u['ip']})");
|
|
||||||
$cmsg->setType(6);
|
|
||||||
$chat->sendMsg($cmsg);
|
|
||||||
}
|
|
||||||
$apu = "auth = '" . md5($u['login'] . 'AUTH' . IP) . "',";
|
|
||||||
setcookie('auth', md5($u['login'] . 'AUTH' . IP), time() + 60 * 60 * 24 * 365, '', Config::get('host'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$ipnew = IP;
|
|
||||||
|
|
||||||
Db::sql('insert into logs_auth (uid, ip, browser, time) values (?,?,?,unix_timestamp())', [
|
|
||||||
$u['id'], IP, $_SERVER['HTTP_USER_AGENT'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
Db::sql("update users set $apu ip = ?, dateEnter = ?, online = unix_timestamp() where id = ?", [$ipnew, $_SERVER['HTTP_USER_AGENT'], $u['id']]);
|
|
||||||
|
|
||||||
$_SESSION['uid'] = $u['id'];
|
|
||||||
header('location: /bk');
|
|
||||||
exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($_SESSION['totp']) && !empty($_SESSION['login'])) {
|
||||||
|
if (empty($otp)) {
|
||||||
|
?>
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<title>Второй пароль</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form method="post">
|
||||||
|
<label for="otp">Одноразовый код:</label><br>
|
||||||
|
<input name="otp" id="otp" minlength="6" maxlength="6" size="6" placeholder="000000" required><br>
|
||||||
|
<input type="submit">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<?php
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SESSION['totp']->generate() !== $otp) {
|
||||||
|
unset($_SESSION['login'], $_SESSION['totp']);
|
||||||
|
error('Неверный одноразовый код!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Db::getValue('select count(*) from stats where id = ?', [$u['id']])) {
|
||||||
|
Db::sql('insert into stats (id, stats) values (?,?)', [$u['id'], 's1=3|s2=3|s3=3|s4=3|rinv=40|m9=5|m6=10']);
|
||||||
|
}
|
||||||
|
if (!Db::getValue('select count(*) from online where uid = ?', [$u['id']])) {
|
||||||
|
Db::sql('insert into online (uid, timeStart) values (?,unix_timestamp())', [$u['id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_COOKIE['login'])) {
|
||||||
|
setcookie('login', '', time() - 60 * 60 * 24, '', Config::get('host'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//мульты
|
||||||
|
if ($u['admin'] === 0) {
|
||||||
|
$ipm1 = Db::getValue(
|
||||||
|
'select ip from logs_auth where uid = ? and ip != ? order by id limit 1',
|
||||||
|
[$u['id'], $u['ip']]
|
||||||
|
);
|
||||||
|
$ppl = Db::getRows(
|
||||||
|
'select * from logs_auth where ip != ? and (ip = ? or ip = ? or ip = ? or ip = ? or ip = ?)',
|
||||||
|
['', $u['ip'], $ipm1, $u['ipreg'], IP, $_COOKIE['ip']]
|
||||||
|
);
|
||||||
|
foreach ($ppl as $item) {
|
||||||
|
$ml = Db::getValue(
|
||||||
|
'select id from mults where (uid = ? and uid2 = ?) or (uid = ? and uid2 = ?) limit 1',
|
||||||
|
[$item['uid'], $u['id'], $u['id'], $item['uid']]
|
||||||
|
);
|
||||||
|
if (!$ml && $item['ip'] !== '' && $item['ip'] !== '127.0.0.1') {
|
||||||
|
Db::sql('insert into mults (uid, uid2, ip) VALUES (?,?,?)', [$u['id'], $item['uid'], $item['ip']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_COOKIE['ip']) && $_COOKIE['ip'] != IP) {
|
||||||
|
Db::sql(
|
||||||
|
'insert into logs_auth (uid, ip, browser, type, time) VALUES (?,?,?,1,unix_timestamp())',
|
||||||
|
[$u['id'], $_COOKIE['ip'], $_SERVER['HTTP_USER_AGENT']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setcookie('login', $_POST['login'] ?? '', time() + 60 * 60 * 24 * 7, '', Config::get('host'));
|
||||||
|
setcookie('ip', IP, time() + 60 * 60 * 24 * 150, '');
|
||||||
|
|
||||||
|
if ($u['online'] < time() - 520) {
|
||||||
|
$sp = Db::getRows('select room, login from users where online > unix_timestamp() - 600 and id in (select user from friends where friend = ?)', [$u['id']]);
|
||||||
|
foreach ($sp as $usr) {
|
||||||
|
$chatDto = new ChatMessage();
|
||||||
|
$chatDto->setRoom($usr['room']);
|
||||||
|
$chatDto->setTo($usr['login']);
|
||||||
|
$chatDto->setText('Вас приветствует: <b>' . $u['login'] . '</b>.');
|
||||||
|
$chatDto->setType(6);
|
||||||
|
$chat->sendMsg($chatDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$apu = '';
|
||||||
|
Db::sql('update dump set ver = 1, upd = 2 where uid = ?', [$u['id']]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
$u['auth'] != md5($u['login'] . 'AUTH' . IP) ||
|
||||||
|
$_COOKIE['auth'] != md5($u['login'] . 'AUTH' . IP) ||
|
||||||
|
$u['auth'] == '' || $u['auth'] == '0'
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
$u['auth'] != '' &&
|
||||||
|
$u['auth'] != '0' &&
|
||||||
|
$u['ip'] != IP
|
||||||
|
) {
|
||||||
|
$cmsg = new ChatMessage();
|
||||||
|
$cmsg->setTo($u['login']);
|
||||||
|
$cmsg->setText('В предыдущий раз этим персонажем заходили с другого компьютера ' . date('d.m.Y H:i', $u['online']) . "(Предыдущий ip: %{$u['ip']})");
|
||||||
|
$cmsg->setType(6);
|
||||||
|
$chat->sendMsg($cmsg);
|
||||||
|
}
|
||||||
|
$apu = "auth = '" . md5($u['login'] . 'AUTH' . IP) . "',";
|
||||||
|
setcookie('auth', md5($u['login'] . 'AUTH' . IP), time() + 60 * 60 * 24 * 365, '', Config::get('host'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$ipnew = IP;
|
||||||
|
|
||||||
|
Db::sql('insert into logs_auth (uid, ip, browser, time) values (?,?,?,unix_timestamp())', [
|
||||||
|
$u['id'], IP, $_SERVER['HTTP_USER_AGENT'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
Db::sql("update users set $apu ip = ?, dateEnter = ?, online = unix_timestamp() where id = ?", [$ipnew, $_SERVER['HTTP_USER_AGENT'], $u['id']]);
|
||||||
|
|
||||||
|
$_SESSION['uid'] = $u['id'];
|
||||||
|
|
||||||
|
unset($_SESSION['login'], $_SESSION['totp']);
|
||||||
|
|
||||||
|
header('location: /bk');
|
||||||
|
exit();
|
||||||
|
110
gate.php
110
gate.php
@ -1,110 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
define('GAME',true);
|
|
||||||
include_once('_incl_data/__config.php');
|
|
||||||
include_once('_incl_data/class/__db_connect.php');
|
|
||||||
|
|
||||||
if( isset($_GET['md5']) ) {
|
|
||||||
$_GET['in'] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isset($_GET['in']) ) {
|
|
||||||
|
|
||||||
$_GET['ref'] = 7;
|
|
||||||
|
|
||||||
$login = $_GET['login'];
|
|
||||||
$pass = $_GET['pass'];
|
|
||||||
|
|
||||||
$md5 = md5( 'GATE_IN_DATA::'.$_GET['login'].$_GET['pass'].$_GET['exp'].$_GET['align'].$_GET['clan_prava'].$_GET['bithday'].$_GET['clan'].$_GET['sex'].$_GET['win'].$_GET['lose'].$_GET['nich'] );
|
|
||||||
|
|
||||||
if( $md5 != $_GET['md5'] ) {
|
|
||||||
unset($_GET['in']);
|
|
||||||
}else{
|
|
||||||
echo 'Нельзя создать т.к. не верный ключ и данные!';
|
|
||||||
}
|
|
||||||
|
|
||||||
if( $_GET['exp'] > 300000 ) {
|
|
||||||
$_GET['exp'] = 300000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( $_GET['clan'] == 1 ) {
|
|
||||||
$_GET['clan'] = 0;
|
|
||||||
$_GET['align'] = 0;
|
|
||||||
$_GET['clan_prava'] = 0;
|
|
||||||
}
|
|
||||||
if( $_GET['clan'] > 1 ) {
|
|
||||||
$_GET['clan'] += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
$usr = mysql_fetch_array(mysql_query('SELECT * FROM `users` WHERE `login` = "'.mysql_real_escape_string($_GET['login']).'" LIMIT 1'));
|
|
||||||
if(isset($usr['id']) && isset($_GET['in'])) {
|
|
||||||
unset($_GET['in']);
|
|
||||||
setcookie('login',$_GET['login'], (time()+60*60*24*7) , '' , '.new-combats.com' );
|
|
||||||
setcookie('pass',$_GET['pass'], (time()+60*60*24*7) , '' , '.new-combats.com' );
|
|
||||||
setcookie('login',$_GET['login'], (time()+60*60*24*7) );
|
|
||||||
setcookie('pass',$_GET['pass'], (time()+60*60*24*7) );
|
|
||||||
header('location: /enter.php?login='.$_GET['login'].'&pass='.$_GET['pass'].'');
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isset($_GET['in']) ) {
|
|
||||||
|
|
||||||
//Создаем персонажа
|
|
||||||
if( (int)$_GET['ref'] > 0 ) {
|
|
||||||
mysql_query("UPDATE `users` SET `referals` = `referals` + 1 WHERE `id` = '".mysql_real_escape_string((int)$_GET['ref'])."' LIMIT 1");
|
|
||||||
}
|
|
||||||
$pass = md5($pass);
|
|
||||||
mysql_query('INSERT INTO `users` (`real`,`online`,`align`,`clan`,`clan_prava`,`win`,`lose`,`nich`,`sex`,`bithday`,`host_reg`,`pass`,`ip`,`ipreg`,`city`,`cityreg`,`room`,`timereg`) VALUES (
|
|
||||||
"1",
|
|
||||||
"'.time().'",
|
|
||||||
"'.mysql_real_escape_string($_GET['align']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['clan']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['clan_prava']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['win']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['lose']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['nich']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['sex']).'",
|
|
||||||
"'.mysql_real_escape_string($_GET['bithday']).'",
|
|
||||||
|
|
||||||
"'.mysql_real_escape_string(0+$_GET['ref']).'",
|
|
||||||
"'.mysql_real_escape_string($pass).'",
|
|
||||||
"'.mysql_real_escape_string(GetRealIpTest()).'",
|
|
||||||
"'.mysql_real_escape_string(GetRealIpTest()).'",
|
|
||||||
"capitalcity",
|
|
||||||
"capitalcity",
|
|
||||||
"0",
|
|
||||||
"'.time().'"
|
|
||||||
)');
|
|
||||||
$uid = mysql_insert_id();
|
|
||||||
if( $uid > 0 ) {
|
|
||||||
|
|
||||||
mysql_query('UPDATE `users` SET `login` = "'.mysql_real_escape_string($login).'" WHERE `id` = "'.$uid.'" LIMIT 1');
|
|
||||||
//Создаем статы персонажа
|
|
||||||
mysql_query("INSERT INTO `online` (`uid`,`timeStart`) VALUES ('".$uid."','".time()."')");
|
|
||||||
mysql_query("INSERT INTO `stats` (`id`,`stats`,`exp`) VALUES ('".$uid."','s1=3|s2=3|s3=3|s4=3|rinv=40|m9=5|m6=10','".mysql_real_escape_string($_GET['exp'])."')");
|
|
||||||
|
|
||||||
//мульты
|
|
||||||
$ipm1 = mysql_fetch_array(mysql_query('SELECT * FROM `logs_auth` WHERE `uid` = "'.mysql_real_escape_string($uid).'" AND `ip`!="'.mysql_real_escape_string(GetRealIpTest()).'" ORDER BY `id` ASC LIMIT 1'));
|
|
||||||
$ppl = mysql_query('SELECT * FROM `logs_auth` WHERE `ip`!="" AND (`ip` = "'.mysql_real_escape_string(GetRealIpTest()).'" OR `ip`="'.mysql_real_escape_string($ipm1['ip']).'" OR `ip`="'.mysql_real_escape_string($_COOKIE['ip']).'")');
|
|
||||||
while($spl = mysql_fetch_array($ppl))
|
|
||||||
{
|
|
||||||
$ml = mysql_fetch_array(mysql_query('SELECT `id` FROM `mults` WHERE (`uid` = "'.$spl['uid'].'" AND `uid2` = "'.$uid.'") OR (`uid2` = "'.$spl['uid'].'" AND `uid` = "'.$uid.'") LIMIT 1'));
|
|
||||||
if(!isset($ml['id']) && $spl['ip']!='' && $spl['ip']!='127.0.0.1')
|
|
||||||
{
|
|
||||||
mysql_query('INSERT INTO `mults` (`uid`,`uid2`,`ip`) VALUES ("'.$uid.'","'.$spl['uid'].'","'.$spl['ip'].'")');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mysql_query("INSERT INTO `logs_auth` (`uid`,`ip`,`browser`,`type`,`time`,`depass`) VALUES ('".$uid."','".mysql_real_escape_string(GetRealIpTest())."','".mysql_real_escape_string($_SERVER['HTTP_USER_AGENT'])."','1','".time()."','')");
|
|
||||||
|
|
||||||
//Обновяем таблицы
|
|
||||||
mysql_query("UPDATE `users` SET `online`='".time()."',`ip` = '".mysql_real_escape_string(GetRealIpTest())."' WHERE `uid` = '".$uid."' LIMIT 1");
|
|
||||||
|
|
||||||
if(!setcookie('login',$login, (time()+60*60*24*7) , '' , '.new-combats.com' ) || !setcookie('pass',$pass, (time()+60*60*24*7) , '' , '.new-combats.com' )) {
|
|
||||||
die('Ошибка сохранения cookie.');
|
|
||||||
}
|
|
||||||
header('location: /enter.php?login='.$_GET['login'].'&pass='.$_GET['pass'].'');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -6,11 +6,6 @@ if (!defined('GAME_VERSION')) {
|
|||||||
require_once '_incl_data/autoload.php';
|
require_once '_incl_data/autoload.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_GET['time'])) {
|
|
||||||
echo time() . '<br>' . date('d.m.Y H:i:s', (int)$_GET['time']);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
header("Cache-Control: max-age=3600");
|
header("Cache-Control: max-age=3600");
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
@ -30,6 +25,7 @@ header("Cache-Control: max-age=3600");
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr.incontent {
|
hr.incontent {
|
||||||
width: 32%;
|
width: 32%;
|
||||||
border: 1px #1c1c1c solid;
|
border: 1px #1c1c1c solid;
|
||||||
@ -43,7 +39,7 @@ header("Cache-Control: max-age=3600");
|
|||||||
<label for="first-name">Ваш Никнейм</label><br>
|
<label for="first-name">Ваш Никнейм</label><br>
|
||||||
<input type="text" id="first-name" name="login" autocomplete="username"><br>
|
<input type="text" id="first-name" name="login" autocomplete="username"><br>
|
||||||
<label for="last-name">Ваш Пароль</label><br>
|
<label for="last-name">Ваш Пароль</label><br>
|
||||||
<input type="password" id="last-name" name="psw" autocomplete="current-password">
|
<input type="password" id="last-name" name="password" autocomplete="current-password">
|
||||||
<p>
|
<p>
|
||||||
<input type="submit" value="Войти в игру" class="btn btn-default">
|
<input type="submit" value="Войти в игру" class="btn btn-default">
|
||||||
</form>
|
</form>
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
/* @var $u User */
|
/* @var $u User */
|
||||||
|
|
||||||
use Core\Config;
|
use Core\Config;
|
||||||
|
use Core\Db;
|
||||||
|
use Core\TOTP;
|
||||||
use User\Email;
|
use User\Email;
|
||||||
use User\Password;
|
use User\Password;
|
||||||
|
|
||||||
@ -14,23 +16,18 @@ $password = new Password($u->info);
|
|||||||
$email = new Email($u->info);
|
$email = new Email($u->info);
|
||||||
$status = null;
|
$status = null;
|
||||||
|
|
||||||
if ($_POST['oldpsw2']) { // remove psw2
|
if ($_POST['removetotp']) {
|
||||||
if (password_verify((int)$_POST['oldpsw2'], $u->info['pass2'])) {
|
// Удаление ключа ТОТР
|
||||||
$u->info['pass2'] = $password->changeSecond(null)['pass2'];
|
$u->info['totp'] = '';
|
||||||
$status = "<b style='color: darkolivegreen'>Второй пароль выключен.</b><br>";
|
Db::sql('update users set totp = ? where id = ?', [$u->info['totp'], $u->info['id']]);
|
||||||
} else {
|
$status = "<b style='color: darkolivegreen'>Секретный ключ удалён.</b><br>";
|
||||||
$status = "<b style='color: red'>Введен не верный второй пароль!</b><br>";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_POST['num_count']) { //add psw2
|
if ($_POST['newtotp']) {
|
||||||
$arr = $password->changeSecond((int)$_POST['num_count']);
|
// Создание ключа ТОТР
|
||||||
$status = "<b style='color: red'>Второй пароль: {$arr['pass2']}.<br>
|
$u->info['totp'] = TOTP::otpSecret($u->info['id']);
|
||||||
Запомните или запишите, т.к. он не высылается на email и его нельзя как-либо узнать.
|
Db::sql('update users set totp = ? where id = ?', [$u->info['totp'], $u->info['id']]);
|
||||||
Потеряв второй пароль, вы потеряете персонажа!<br>
|
$status = "<b style='color: darkolivegreen'>Секретный ключ создан.</b><br>";
|
||||||
Этот пароль выслан на ваш email.<br>
|
|
||||||
</b><br>";
|
|
||||||
$u->info['pass2'] = $arr['hash'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -66,7 +63,7 @@ if (
|
|||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<form action="main.php?security" method="post" id="security"></form>
|
<form action="/main.php?security" method="post" id="security"></form>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h3>Настройки безопасности</h3>
|
<h3>Настройки безопасности</h3>
|
||||||
@ -180,41 +177,18 @@ if (
|
|||||||
</TABLE>
|
</TABLE>
|
||||||
</FIELDSET>
|
</FIELDSET>
|
||||||
<FIELDSET>
|
<FIELDSET>
|
||||||
<LEGEND><B> Второй уровень защиты </B></LEGEND>
|
<LEGEND><B> TOTP </B></LEGEND>
|
||||||
Настоятельно рекомендуем включить второй уровень защиты.<BR>
|
TOTP (Time-based One-Time Password) - это метод двухфакторной аутентификации, который генерирует одноразовый пароль на основе текущего времени.
|
||||||
На компьютере может быть установлен клавиатурный шпион, который записывает все нажатия клавиш, таким
|
Устанавливается для повышения безопасности вашего аккаунта, так как помогает защитить его от несанкционированного доступа.<br>
|
||||||
образом,
|
Вы можете использовать TOTP приложения, такие как Google Authenticator или Authy, чтобы генерировать и отображать временные одноразовые пароли на вашем мобильном устройстве.
|
||||||
могут узнать ваш пароль.<BR>
|
<br><br>
|
||||||
Возможно, в сети компьютеров установлен "сетевой снифер", перехватывающий все интернет пакеты, который легко
|
<U>Будьте внимательны!</U> Секретный ключ генерируется только один раз и не подлежит восстановлению. Его можно только удалить или заменить новым.<br>
|
||||||
покажет все пароли. Чтобы обезопасить себя, вы можете установить своему персонажу второй пароль, который
|
<?php if (!empty($u->info['totp'])): ?>
|
||||||
можно
|
<br><b>Секретный ключ:</b>
|
||||||
вводить при помощи мышки (клавиатурным шпионом не перехватить) и который передается на игровой сервер в
|
<pre>{$u->info['totp']}</pre><br><br>
|
||||||
зашифрованном виде, не поддающимся расшифровке ("сетевой снифер" не сможет перехватить его).<BR>
|
<input form='security' type='submit' name='removetotp' value='Удалить секретный ключ' disabled><br>
|
||||||
<U>Будьте внимательны!</U> Второй пароль отправляется на email один раз,при установке второго уровня защиты!<BR>
|
<?php endif; ?>
|
||||||
|
<input form='security' type='submit' name='newtotp' value='Создать новый секретный ключ' disabled><br>
|
||||||
<?php
|
|
||||||
if (!empty($u->info['pass2'])) {
|
|
||||||
echo "<BR><B>Второй пароль установлен.</B><BR><BR>
|
|
||||||
Введите второй пароль <INPUT TYPE=password NAME=oldpsw2 size=10 maxlength=8>
|
|
||||||
<INPUT form='security' TYPE=submit name=changepsw value=\"Выключить второй пароль\" onclick=\"return confirm('Выключить запрос второго пароля при входе в Бойцовский Клуб?')\">";
|
|
||||||
} else {
|
|
||||||
?>
|
|
||||||
Длина пароля:<BR>
|
|
||||||
<label>
|
|
||||||
<INPUT form="security" TYPE=radio NAME="num_count" value=4> 4 знака<BR>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<INPUT form="security" TYPE=radio NAME="num_count" checked value=6> 6 знаков<BR>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<INPUT form="security" TYPE=radio NAME="num_count" value=8> 8 знаков<BR>
|
|
||||||
</label>
|
|
||||||
<INPUT form="security" TYPE=submit name=changepsw value="Установить второй пароль"
|
|
||||||
onclick="return confirm('Система сама придумает вам второй пароль, он будет показан на этой странице, после того, как вы нажмете OK и продублирован на email, указанный при регистрации. Будьте внимательны.\nУстановить второй пароль?')">
|
|
||||||
<BR>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</FIELDSET>
|
</FIELDSET>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user