Использование базового TOTP через мобильное приложение вместо существующей реализации второго пароля на javascript.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
use Core\Config;
|
||||
use Core\Database;
|
||||
use Core\Db;
|
||||
use Core\TOTP;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use User\Password;
|
||||
use User\UserIp;
|
||||
|
||||
@@ -15,43 +17,36 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . '_incl_data/autoload.php';
|
||||
Database::init();
|
||||
|
||||
define('IP', UserIp::get());
|
||||
|
||||
$chat = new Chat();
|
||||
$login = $_SESSION['login'] ?? '';
|
||||
$password = '';
|
||||
$otp = '';
|
||||
|
||||
if (isset($_GET['login'])) {
|
||||
$_POST['login'] = $_GET['login'];
|
||||
$_POST['pass'] = $_GET['pass'];
|
||||
$_POST['code'] = $_GET['code'];
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['login'])) {
|
||||
$login = $_POST['login'];
|
||||
}
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
}
|
||||
if (isset($_POST['otp'])) {
|
||||
$otp = $_POST['otp'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['psw'])) {
|
||||
$_POST['pass'] = $_POST['psw'];
|
||||
}
|
||||
|
||||
if (isset($_SESSION['login'])) {
|
||||
$_POST['login'] = $_SESSION['login'];
|
||||
$_POST['pass'] = $_SESSION['pass'];
|
||||
}
|
||||
|
||||
function error($e)
|
||||
#[NoReturn] function error($e): void
|
||||
{
|
||||
die(
|
||||
'
|
||||
<link rel="stylesheet" href="error.css">
|
||||
<div class="text-wrapper">
|
||||
<div class="title" data-content="Ошибка">
|
||||
Ошибка!!
|
||||
$returnLink = Config::get('https');
|
||||
$html = <<<HTML
|
||||
<link rel="stylesheet" href="error.css">
|
||||
<div class="text-wrapper">
|
||||
<div class="title" data-content="Ошибка">Ошибка!!</div>
|
||||
<div class="subtitle">$e</div>
|
||||
<div class="buttons"><a class="button" href="$returnLink">Вернуться назад</a></div>
|
||||
</div>
|
||||
|
||||
<div class="subtitle">
|
||||
' . $e . '
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="button" href="' . Config::get('https') . '">Вернуться назад</a>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
);
|
||||
HTML;
|
||||
exit($html);
|
||||
}
|
||||
|
||||
$u = Db::getRow(
|
||||
@@ -60,259 +55,154 @@ $u = Db::getRow(
|
||||
users.login,
|
||||
auth,
|
||||
pass,
|
||||
pass2,
|
||||
users.city,
|
||||
totp,
|
||||
users.ip,
|
||||
ipreg,
|
||||
admin,
|
||||
online,
|
||||
banned,
|
||||
host_reg,
|
||||
timereg,
|
||||
securetime,
|
||||
users_delo.text as block_reason
|
||||
from users
|
||||
left join users_delo on users.id = users_delo.uid
|
||||
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'])) {
|
||||
error('Логин "' . $_POST['login'] . '" не найден в базе.');
|
||||
} elseif ($u['banned'] > 0) {
|
||||
$blockstr = "Персонаж <b>{$u['login']}</b> заблокирован.";
|
||||
$blockstr .= $u['block_reason'] ? "Причина блокировки: {$u['block_reason']}<br><br>" : '<br><br>';
|
||||
error($blockstr);
|
||||
} elseif (!Password::isGood($_POST['pass'], $u['pass'], $u['login'])) {
|
||||
error("Неверный пароль к персонажу {$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) {
|
||||
if (empty($_SESSION['login'])) {
|
||||
if (!isset($u['id'])) {
|
||||
error('Логин "' . $login . '" не найден в базе.');
|
||||
} elseif ($u['banned'] > 0) {
|
||||
$blockstr = "Персонаж <b>{$u['login']}</b> заблокирован.";
|
||||
$blockstr .= $u['block_reason'] ? "Причина блокировки: {$u['block_reason']}<br><br>" : '<br><br>';
|
||||
error($blockstr);
|
||||
} elseif (!Password::isGood($password, $u['pass'], $u['login'])) {
|
||||
Db::sql(
|
||||
'insert into logs_auth (uid, ip, browser, type, time) VALUES (?,?,?,1,unix_timestamp())',
|
||||
[$u['id'], $_COOKIE['ip'], $_SERVER['HTTP_USER_AGENT']]
|
||||
'insert into logs_auth (uid, ip, browser, type, time) values (?,?,?,3,unix_timestamp())',
|
||||
[$u['id'], IP, $_SERVER['HTTP_USER_AGENT']]
|
||||
);
|
||||
error("Неверный пароль к персонажу {$u['login']}.");
|
||||
}
|
||||
|
||||
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, 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);
|
||||
}
|
||||
$_SESSION['login'] = $u['login'];
|
||||
if (!empty($u['totp'])) {
|
||||
$_SESSION['totp'] = new TOTP($u['totp']);
|
||||
}
|
||||
|
||||
$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();
|
||||
|
||||
Reference in New Issue
Block a user