[Web] multiple tfa - user support
This commit is contained in:
		| @@ -936,24 +936,39 @@ function check_login($user, $pass, $app_passwd_data = false) { | |||||||
|     $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); |     $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); | ||||||
|   } |   } | ||||||
|   foreach ($rows as $row) { |   foreach ($rows as $row) { | ||||||
|  |     // verify password | ||||||
|     if (verify_hash($row['password'], $pass) !== false) { |     if (verify_hash($row['password'], $pass) !== false) { | ||||||
|       unset($_SESSION['ldelay']); |       // check for tfa authenticators | ||||||
|       $_SESSION['return'][] =  array( |       $authenticators = get_tfa($user); | ||||||
|         'type' => 'success', |       if (isset($authenticators['additional']) && is_array($authenticators['additional']) && count($authenticators['additional']) > 0) { | ||||||
|         'log' => array(__FUNCTION__, $user, '*'), |         $_SESSION['pending_mailcow_cc_username'] = $user; | ||||||
|         'msg' => array('logged_in_as', $user) |         $_SESSION['pending_mailcow_cc_role'] = "user"; | ||||||
|       ); |         $_SESSION['pending_tfa_methods'] = $authenticators['additional']; | ||||||
|       if ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { |         unset($_SESSION['ldelay']); | ||||||
|         $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; |         $_SESSION['return'][] =  array( | ||||||
|         $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); |           'type' => 'success', | ||||||
|         $stmt->execute(array( |           'log' => array(__FUNCTION__, $user, '*'), | ||||||
|           ':service' => $service, |           'msg' => array('logged_in_as', $user) | ||||||
|           ':app_id' => $row['app_passwd_id'], |         ); | ||||||
|           ':username' => $user, |         return "pending"; | ||||||
|           ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) |       } 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"; |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -61,9 +61,9 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) { | |||||||
| 		header("Location: /user"); | 		header("Location: /user"); | ||||||
| 	} | 	} | ||||||
| 	elseif ($as != "pending") { | 	elseif ($as != "pending") { | ||||||
|         unset($_SESSION['pending_mailcow_cc_username']); |     unset($_SESSION['pending_mailcow_cc_username']); | ||||||
|         unset($_SESSION['pending_mailcow_cc_role']); |     unset($_SESSION['pending_mailcow_cc_role']); | ||||||
|         unset($_SESSION['pending_tfa_methods']); |     unset($_SESSION['pending_tfa_methods']); | ||||||
| 		unset($_SESSION['mailcow_cc_username']); | 		unset($_SESSION['mailcow_cc_username']); | ||||||
| 		unset($_SESSION['mailcow_cc_role']); | 		unset($_SESSION['mailcow_cc_role']); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -15,6 +15,10 @@ | |||||||
|               <i class="bi bi-inbox-fill"></i> {{ lang.user.open_webmail_sso }} |               <i class="bi bi-inbox-fill"></i> {{ lang.user.open_webmail_sso }} | ||||||
|             </a> |             </a> | ||||||
|           {% endif %} |           {% endif %} | ||||||
|  |           <div> | ||||||
|  |             <hr> | ||||||
|  |             <p><a href="#pwChangeModal" data-toggle="modal"><i class="bi bi-pencil-fill"></i> {{ lang.user.change_password }}</a></p> | ||||||
|  |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|       <hr> |       <hr> | ||||||
| @@ -40,8 +44,27 @@ | |||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|           <p>{{ mailboxdata.quota_used|formatBytes(2) }} / {% if mailboxdata.quota == 0 %}∞{% else %}{{ mailboxdata.quota|formatBytes(2) }}{% endif %}<br>{{ mailboxdata.messages }} {{ lang.user.messages }}</p> |           <p>{{ mailboxdata.quota_used|formatBytes(2) }} / {% if mailboxdata.quota == 0 %}∞{% else %}{{ mailboxdata.quota|formatBytes(2) }}{% endif %}<br>{{ mailboxdata.messages }} {{ lang.user.messages }}</p> | ||||||
|           <hr> |         </div> | ||||||
|           <p><a href="#pwChangeModal" data-toggle="modal"><i class="bi bi-pencil-fill"></i> {{ lang.user.change_password }}</a></p> |       </div> | ||||||
|  |       <hr> | ||||||
|  |       {# TFA #} | ||||||
|  |       <div class="row"> | ||||||
|  |         <div class="col-sm-3 col-xs-5 text-right">{{ lang.tfa.tfa }}:</div> | ||||||
|  |         <div class="col-sm-9 col-xs-7"> | ||||||
|  |           <p id="tfa_pretty">{{ tfa_data.pretty }}</p> | ||||||
|  |           {% include 'tfa_keys.twig' %} | ||||||
|  |           <br> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="row"> | ||||||
|  |         <div class="col-sm-3 col-xs-5 text-right">{{ lang.tfa.set_tfa }}:</div> | ||||||
|  |         <div class="col-sm-9 col-xs-7"> | ||||||
|  |           <select data-style="btn btn-sm dropdown-toggle bs-placeholder btn-default" data-width="fit" id="selectTFA" class="selectpicker" title="{{ lang.tfa.select }}"> | ||||||
|  |             <option value="yubi_otp">{{ lang.tfa.yubi_otp }}</option> | ||||||
|  |             <option value="webauthn">{{ lang.tfa.webauthn }}</option> | ||||||
|  |             <option value="totp">{{ lang.tfa.totp }}</option> | ||||||
|  |             <option value="none">{{ lang.tfa.none }}</option> | ||||||
|  |           </select> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|       <hr> |       <hr> | ||||||
|   | |||||||
| @@ -76,6 +76,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == ' | |||||||
|     'acl_json' => json_encode($_SESSION['acl']), |     'acl_json' => json_encode($_SESSION['acl']), | ||||||
|     'user_spam_score' => mailbox('get', 'spam_score', $username), |     'user_spam_score' => mailbox('get', 'spam_score', $username), | ||||||
|     'tfa_data' => $tfa_data, |     'tfa_data' => $tfa_data, | ||||||
|  |     'tfa_id' => @$_SESSION['tfa_id'], | ||||||
|     'fido2_data' => $fido2_data, |     'fido2_data' => $fido2_data, | ||||||
|     'mailboxdata' => $mailboxdata, |     'mailboxdata' => $mailboxdata, | ||||||
|     'clientconfigstr' => $clientconfigstr, |     'clientconfigstr' => $clientconfigstr, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user