Skip to content

Commit

Permalink
Merge pull request SimpleMachines#2577 from Dragooon/release-2.1
Browse files Browse the repository at this point in the history
Minor 2FA and SSL improvements
  • Loading branch information
Dragooon committed Dec 6, 2014
2 parents 544d438 + 76c400d commit 7da1add
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 11 deletions.
3 changes: 2 additions & 1 deletion Sources/Load.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,8 @@ function loadUserSettings()
// 2. RSS feeds and XMLHTTP requests don't count either.
// 3. If it was set within this session, no need to set it again.
// 4. New session, yet updated < five hours ago? Maybe cache can help.
if (SMF != 'SSI' && !isset($_REQUEST['xml']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] != '.xml') && empty($_SESSION['id_msg_last_visit']) && (empty($modSettings['cache_enable']) || ($_SESSION['id_msg_last_visit'] = cache_get_data('user_last_visit-' . $id_member, 5 * 3600)) === null))
// 5. We're still logging in or authenticating
if (SMF != 'SSI' && !isset($_REQUEST['xml']) && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('.xml', 'login2', 'logintfa'))) && empty($_SESSION['id_msg_last_visit']) && (empty($modSettings['cache_enable']) || ($_SESSION['id_msg_last_visit'] = cache_get_data('user_last_visit-' . $id_member, 5 * 3600)) === null))
{
// @todo can this be cached?
// Do a quick query to make sure this isn't a mistake.
Expand Down
17 changes: 15 additions & 2 deletions Sources/LogInOut.php
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ function Login2()
*/
function LoginTFA()
{
global $sourcedir, $txt, $context, $user_info, $modSettings;
global $sourcedir, $txt, $context, $user_info, $modSettings, $scripturl;

if (!$user_info['is_guest'] || empty($context['tfa_member']) || empty($modSettings['tfa_mode']))
fatal_lang_error('no_access', false);
Expand All @@ -421,6 +421,10 @@ function LoginTFA()

if (!empty($_POST['tfa_code']) && empty($_POST['tfa_backup']))
{
// Check to ensure we're forcing SSL for authentication
if (!empty($modSettings['force_ssl']) && empty($maintenance) && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'))
fatal_lang_error('login_ssl_required');

$code = $_POST['tfa_code'];

if (strlen($code) == $totp->getCodeLength() && $totp->validateCode($code))
Expand All @@ -440,6 +444,10 @@ function LoginTFA()
}
elseif (!empty($_POST['tfa_backup']))
{
// Check to ensure we're forcing SSL for authentication
if (!empty($modSettings['force_ssl']) && empty($maintenance) && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'))
fatal_lang_error('login_ssl_required');

$backup = $_POST['tfa_backup'];

if (hash_verify_password($member['member_name'], $backup, $member['tfa_backup']))
Expand All @@ -448,6 +456,7 @@ function LoginTFA()
updateMemberData($member['id_member'], array(
'tfa_secret' => '',
'tfa_backup' => '',
'last_login' => time(),
));
setTFACookie(3153600, $member['id_member'], hash_salt($member['tfa_backup'], $member['password_salt']));
redirectexit('action=profile;area=tfasetup;backup');
Expand All @@ -465,6 +474,7 @@ function LoginTFA()
loadTemplate('Login');
$context['sub_template'] = 'login_tfa';
$context['page_title'] = $txt['login'];
$context['tfa_url'] = (!empty($modSettings['force_ssl']) && $modSettings['force_ssl'] < 2 ? strtr($scripturl, array('http://' => 'https://')) : $scripturl) . '?action=logintfa';
}

/**
Expand Down Expand Up @@ -568,7 +578,10 @@ function DoLogin()
$smcFunc['db_free_result']($request);

// You've logged in, haven't you?
updateMemberData($user_info['id'], array('last_login' => time(), 'member_ip' => $user_info['ip'], 'member_ip2' => $_SERVER['BAN_CHECK_IP']));
$update = array('member_ip' => $user_info['ip'], 'member_ip2' => $_SERVER['BAN_CHECK_IP']);
if (empty($user_settings['tfa_secret']))
$update['last_login'] = time();
updateMemberData($user_info['id'], $update);

// Get rid of the online entry for that old guest....
$smcFunc['db_query']('', '
Expand Down
2 changes: 1 addition & 1 deletion Sources/Logging.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ function writeLog($force = false)
$_SESSION['timeOnlineUpdated'] = time();

// Set their login time, if not already done within the last minute.
if (SMF != 'SSI' && !empty($user_info['last_login']) && $user_info['last_login'] < time() - 60)
if (SMF != 'SSI' && !empty($user_info['last_login']) && $user_info['last_login'] < time() - 60 && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('.xml', 'login2', 'logintfa'))))
{
// Don't count longer than 15 minutes.
if (time() - $_SESSION['timeOnlineUpdated'] > 60 * 15)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Profile-Modify.php
Original file line number Diff line number Diff line change
Expand Up @@ -3983,6 +3983,10 @@ function tfasetup($memID)
// If TFA has not been setup, allow them to set it up
if (empty($user_settings['tfa_secret']) && $context['user']['is_owner'])
{
// Check to ensure we're forcing SSL for authentication
if (!empty($modSettings['force_ssl']) && empty($maintenance) && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'))
fatal_lang_error('login_ssl_required');

// In some cases (forced 2FA or backup code) they would be forced to be redirected here,
// we do not want too much AJAX to confuse them.
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && !isset($_REQUEST['backup']) && !isset($_REQUEST['forced']))
Expand Down
4 changes: 4 additions & 0 deletions Sources/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,10 @@ function ModifyProfile($post_errors = array())

if ($check_password)
{
// Check to ensure we're forcing SSL for authentication
if (!empty($modSettings['force_ssl']) && empty($maintenance) && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'))
fatal_lang_error('login_ssl_required');

// You didn't even enter a password!
if (trim($_POST['oldpasswrd']) == '')
$post_errors[] = 'no_password';
Expand Down
4 changes: 4 additions & 0 deletions Sources/Security.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ function validateSession($type = 'admin')
// Posting the password... check it.
if (isset($_POST[$type. '_pass']))
{
// Check to ensure we're forcing SSL for authentication
if (!empty($modSettings['force_ssl']) && empty($maintenance) && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on'))
fatal_lang_error('login_ssl_required');

checkSession();

$good_password = in_array(true, call_integration_hook('integrate_verify_password', array($user_info['username'], $_POST[$type . '_pass'], false)), true);
Expand Down
4 changes: 2 additions & 2 deletions Themes/default/Login.template.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function template_login()
setTimeout(function() {
document.getElementById("', !empty($context['from_ajax']) ? 'ajax_' : '', isset($context['default_username']) && $context['default_username'] != '' ? 'loginpass' : 'loginuser', '").focus();
}, 150);';
if (!empty($context['from_ajax']))
if (!empty($context['from_ajax']) && (empty($modSettings['force_ssl']) || $modSettings['force_ssl'] == 2))
echo '
form = $("#frmLogin");
form.submit(function(e) {
Expand Down Expand Up @@ -121,7 +121,7 @@ function template_login_tfa()
echo '
<div class="error">', $txt['tfa_' . (!empty($context['tfa_error']) ? 'code_' : 'backup_') . 'invalid'], '</div>';
echo '
<form action="', $scripturl, '?action=logintfa" method="post" id="frmTfa">
<form action="', $context['tfa_url'], '" method="post" id="frmTfa">
<div id="tfaCode">
', $txt['tfa_login_desc'], '<br />
<strong>', $txt['tfa_code'], ':</strong>
Expand Down
13 changes: 8 additions & 5 deletions Themes/default/Profile.template.php
Original file line number Diff line number Diff line change
Expand Up @@ -1251,12 +1251,15 @@ function template_statPanel()
// Template for editing profile options.
function template_edit_options()
{
global $context, $scripturl, $txt;
global $context, $scripturl, $txt, $modSettings;

// The main header!
// because some browsers ignore autocomplete=off and fill username in display name and/ or email field, fake them out.
// because some browsers ignore autocomplete=off and fill username in display name and/ or email field, fake them out.
$url = !empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=' . $context['menu_item_selected'] . ';u=' . $context['id_member'];
$url = $context['require_password'] && !empty($modSettings['force_ssl']) && $modSettings['force_ssl'] < 2 ? strtr($url, array('http://' => 'https://')) : $url;

echo '
<form action="', (!empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=' . $context['menu_item_selected'] . ';u=' . $context['id_member']), '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data"', ($context['menu_item_selected'] == 'account' ? ' autocomplete="off"' : ''), '>
<form action="', $url, '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data"', ($context['menu_item_selected'] == 'account' ? ' autocomplete="off"' : ''), '>
<div style="position:absolute; top:-100px;"><input type="text" id="autocompleteFakeName"/><input type="password" id="autocompleteFakePassword"/></div>
<div class="cat_bar">
<h3 class="catbg profile_hd">';
Expand Down Expand Up @@ -2947,7 +2950,7 @@ function template_tfasetup_backup()

function template_profile_tfa()
{
global $context, $txt, $scripturl;
global $context, $txt, $scripturl, $modSettings;

echo '
<dt>
Expand All @@ -2957,7 +2960,7 @@ function template_profile_tfa()
<dd>';
if (!$context['tfa_enabled'] && $context['user']['is_owner'])
echo '
<a href="', $scripturl, '?action=profile;area=tfasetup" id="enable_tfa" onclick="return reqOverlayDiv(this.href, ', JavaScriptEscape($txt['tfa_profile_enable']), ');">', $txt['tfa_profile_enable'], '</a>';
<a href="', !empty($modSettings['force_ssl']) && $modSettings['force_ssl'] < 2 ? strtr($scripturl, array('http://' => 'https://')) : $scripturl, '?action=profile;area=tfasetup" id="enable_tfa">', $txt['tfa_profile_enable'], '</a>';
elseif (!$context['tfa_enabled'])
echo '
', $txt['tfa_profile_disabled'];
Expand Down

0 comments on commit 7da1add

Please sign in to comment.