misuzu/public/auth/twofactor.php

89 lines
3 KiB
PHP
Raw Normal View History

2019-03-10 18:27:44 +00:00
<?php
namespace Misuzu;
2019-03-10 18:27:44 +00:00
require_once '../../misuzu.php';
2019-06-10 17:04:53 +00:00
if(user_session_active()) {
url_redirect('index');
2019-03-10 18:27:44 +00:00
return;
}
2019-03-18 21:30:19 +00:00
$twofactor = !empty($_POST['twofactor']) && is_array($_POST['twofactor']) ? $_POST['twofactor'] : [];
2019-03-10 18:27:44 +00:00
$notices = [];
$ipAddress = ip_remote_address();
$remainingAttempts = user_login_attempts_remaining($ipAddress);
$tokenInfo = user_auth_tfa_token_info(
2019-03-18 21:30:19 +00:00
!empty($_GET['token']) && is_string($_GET['token']) ? $_GET['token'] : (
!empty($twofactor['token']) && is_string($twofactor['token']) ? $twofactor['token'] : ''
)
2019-03-10 18:27:44 +00:00
);
// checking user_totp_key specifically because there's a fringe chance that
// there's a token present, but totp is actually disabled
2019-06-10 17:04:53 +00:00
if(empty($tokenInfo['user_totp_key'])) {
url_redirect('auth-login');
2019-03-10 18:27:44 +00:00
return;
}
2019-06-10 17:04:53 +00:00
while(!empty($twofactor)) {
if(!csrf_verify_request()) {
2019-03-10 18:27:44 +00:00
$notices[] = 'Was unable to verify the request, please try again!';
break;
}
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
2019-03-18 21:30:19 +00:00
$redirect = !empty($twofactor['redirect']) && is_string($twofactor['redirect']) ? $twofactor['redirect'] : '';
2019-03-10 18:27:44 +00:00
2019-06-10 17:04:53 +00:00
if(empty($twofactor['code']) || !is_string($twofactor['code'])) {
2019-03-10 18:27:44 +00:00
$notices[] = 'Code field was empty.';
break;
}
2019-06-10 17:04:53 +00:00
if($remainingAttempts < 1) {
2019-03-10 18:27:44 +00:00
$notices[] = 'There are too many failed login attempts from your IP address, please try again later.';
break;
}
$currentCode = totp_generate($tokenInfo['user_totp_key']);
$previousCode = totp_generate($tokenInfo['user_totp_key'], time() - 30);
2019-03-10 18:27:44 +00:00
2019-06-10 17:04:53 +00:00
if($currentCode !== $twofactor['code'] && $previousCode !== $twofactor['code']) {
2019-03-10 18:27:44 +00:00
$notices[] = sprintf(
"Invalid two factor code, %d attempt%s remaining",
$remainingAttempts - 1,
$remainingAttempts === 2 ? '' : 's'
);
user_login_attempt_record(false, $tokenInfo['user_id'], $ipAddress, $userAgent);
break;
}
user_login_attempt_record(true, $tokenInfo['user_id'], $ipAddress, $userAgent);
$sessionKey = user_session_create($tokenInfo['user_id'], $ipAddress, $userAgent);
2019-06-10 17:04:53 +00:00
if(empty($sessionKey)) {
2019-03-10 18:27:44 +00:00
$notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!";
break;
}
user_auth_tfa_token_invalidate($tokenInfo['tfa_token']);
user_session_start($tokenInfo['user_id'], $sessionKey);
$cookieLife = strtotime(user_session_current('session_expires'));
$cookieValue = Base64::encode(user_session_cookie_pack($tokenInfo['user_id'], $sessionKey), true);
2019-08-14 19:44:30 +00:00
setcookie('msz_auth', $cookieValue, $cookieLife, '/', '', !empty($_SERVER['HTTPS']), true);
2019-03-10 18:27:44 +00:00
2019-06-10 17:04:53 +00:00
if(!is_local_url($redirect)) {
2019-03-10 18:27:44 +00:00
$redirect = url('index');
}
redirect($redirect);
2019-03-10 18:27:44 +00:00
return;
}
echo tpl_render('auth.twofactor', [
'twofactor_notices' => $notices,
2019-03-18 21:30:19 +00:00
'twofactor_redirect' => !empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : url('index'),
2019-03-10 18:27:44 +00:00
'twofactor_attempts_remaining' => $remainingAttempts,
'twofactor_token' => $tokenInfo['tfa_token'],
]);