diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 384905d4..12efd60b 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -936,24 +936,39 @@ function check_login($user, $pass, $app_passwd_data = false) { $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); } foreach ($rows as $row) { + // verify password if (verify_hash($row['password'], $pass) !== false) { - unset($_SESSION['ldelay']); - $_SESSION['return'][] = array( - 'type' => 'success', - 'log' => array(__FUNCTION__, $user, '*'), - 'msg' => array('logged_in_as', $user) - ); - if ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { - $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; - $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); - $stmt->execute(array( - ':service' => $service, - ':app_id' => $row['app_passwd_id'], - ':username' => $user, - ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) - )); + // check for tfa authenticators + $authenticators = get_tfa($user); + if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0) { + $_SESSION['pending_mailcow_cc_username'] = $user; + $_SESSION['pending_mailcow_cc_role'] = "user"; + $_SESSION['pending_tfa_methods'] = $authenticators['additional']; + unset($_SESSION['ldelay']); + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array(__FUNCTION__, $user, '*'), + 'msg' => array('logged_in_as', $user) + ); + return "pending"; + } else { + if ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { + $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; + $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); + $stmt->execute(array( + ':service' => $service, + ':app_id' => $row['app_passwd_id'], + ':username' => $user, + ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) + )); + } + + unset($_SESSION['ldelay']); + // Reactivate TFA if it was set to "deactivate TFA for next login" + $stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user"); + $stmt->execute(array(':user' => $user)); + return "user"; } - return "user"; } } diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php index 1e2bdb42..aec043e9 100644 --- a/data/web/inc/triggers.inc.php +++ b/data/web/inc/triggers.inc.php @@ -61,9 +61,9 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) { header("Location: /user"); } elseif ($as != "pending") { - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); unset($_SESSION['mailcow_cc_username']); unset($_SESSION['mailcow_cc_role']); } diff --git a/data/web/templates/user/tab-user-auth.twig b/data/web/templates/user/tab-user-auth.twig index e1f84fff..0d4c6f32 100644 --- a/data/web/templates/user/tab-user-auth.twig +++ b/data/web/templates/user/tab-user-auth.twig @@ -15,6 +15,10 @@ {{ lang.user.open_webmail_sso }} {% endif %} +
+
+

{{ lang.user.change_password }}

+

@@ -40,8 +44,27 @@

{{ mailboxdata.quota_used|formatBytes(2) }} / {% if mailboxdata.quota == 0 %}∞{% else %}{{ mailboxdata.quota|formatBytes(2) }}{% endif %}
{{ mailboxdata.messages }} {{ lang.user.messages }}

-
-

{{ lang.user.change_password }}

+ + +
+ {# TFA #} +
+
{{ lang.tfa.tfa }}:
+
+

{{ tfa_data.pretty }}

+ {% include 'tfa_keys.twig' %} +
+
+
+
+
{{ lang.tfa.set_tfa }}:
+
+

diff --git a/data/web/user.php b/data/web/user.php index 5bf60917..d7faf791 100644 --- a/data/web/user.php +++ b/data/web/user.php @@ -76,6 +76,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == ' 'acl_json' => json_encode($_SESSION['acl']), 'user_spam_score' => mailbox('get', 'spam_score', $username), 'tfa_data' => $tfa_data, + 'tfa_id' => @$_SESSION['tfa_id'], 'fido2_data' => $fido2_data, 'mailboxdata' => $mailboxdata, 'clientconfigstr' => $clientconfigstr,