[Web] fix yubi otp

This commit is contained in:
FreddleSpl0it 2022-03-19 20:18:31 +01:00
parent 70921b8d15
commit 6d3798ad08
No known key found for this signature in database
GPG Key ID: 6315227FF33D2425
1 changed files with 2 additions and 71 deletions

View File

@ -1626,28 +1626,12 @@ function verify_tfa_login($username, $_data) {
global $tfa; global $tfa;
global $WebAuthn; global $WebAuthn;
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_post_data_log'),
'msg' => $_data
);
if ($_data['tfa_method'] != 'u2f'){ if ($_data['tfa_method'] != 'u2f'){
$stmt = $pdo->prepare("SELECT `authmech` FROM `tfa` $stmt = $pdo->prepare("SELECT `authmech` FROM `tfa`
WHERE `username` = :username AND `id` = :id AND `active` = '1'"); WHERE `username` = :username AND `id` = :id AND `active` = '1'");
$stmt->execute(array(':username' => $username, ':id' => $_data['id'])); $stmt->execute(array(':username' => $username, ':id' => $_data['id']));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_verify_authmech'),
'msg' => $row
);
switch ($row["authmech"]) { switch ($row["authmech"]) {
case "yubi_otp": case "yubi_otp":
if (!ctype_alnum($_data['token']) || strlen($_data['token']) != 44) { if (!ctype_alnum($_data['token']) || strlen($_data['token']) != 44) {
@ -1662,8 +1646,8 @@ function verify_tfa_login($username, $_data) {
$stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa` $stmt = $pdo->prepare("SELECT `id`, `secret` FROM `tfa`
WHERE `username` = :username WHERE `username` = :username
AND `authmech` = 'yubi_otp' AND `authmech` = 'yubi_otp'
AND `id` = ':id' AND `id` = :id
AND `active`='1' AND `active` = '1'
AND `secret` LIKE :modhex"); AND `secret` LIKE :modhex");
$stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id, ':id' => $_data['id'])); $stmt->execute(array(':username' => $username, ':modhex' => '%' . $yubico_modhex_id, ':id' => $_data['id']));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
@ -1734,7 +1718,6 @@ function verify_tfa_login($username, $_data) {
} }
break; break;
case "webauthn": case "webauthn":
// prepare authenticator data
$tokenData = json_decode($_data['token']); $tokenData = json_decode($_data['token']);
$clientDataJSON = base64_decode($tokenData->clientDataJSON); $clientDataJSON = base64_decode($tokenData->clientDataJSON);
$authenticatorData = base64_decode($tokenData->authenticatorData); $authenticatorData = base64_decode($tokenData->authenticatorData);
@ -1742,28 +1725,10 @@ function verify_tfa_login($username, $_data) {
$id = base64_decode($tokenData->id); $id = base64_decode($tokenData->id);
$challenge = $_SESSION['challenge']; $challenge = $_SESSION['challenge'];
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_try_verify'),
'msg' => 'try grab authenticator'
);
// fetch authenticator
$stmt = $pdo->prepare("SELECT `id`, `key_id`, `keyHandle`, `username`, `publicKey` FROM `tfa` WHERE `id` = :id AND `active`='1'"); $stmt = $pdo->prepare("SELECT `id`, `key_id`, `keyHandle`, `username`, `publicKey` FROM `tfa` WHERE `id` = :id AND `active`='1'");
$stmt->execute(array(':id' => $_data['id'])); $stmt->execute(array(':id' => $_data['id']));
$process_webauthn = $stmt->fetch(PDO::FETCH_ASSOC); $process_webauthn = $stmt->fetch(PDO::FETCH_ASSOC);
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_authenticator_grabbed'),
'msg' => 'grabbed authenticator from db'
);
// return err if no authenticator was found
if (empty($process_webauthn)){ if (empty($process_webauthn)){
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
'type' => 'danger', 'type' => 'danger',
@ -1773,7 +1738,6 @@ function verify_tfa_login($username, $_data) {
return false; return false;
} }
// return err if authenticator has no publicKey
if (empty($process_webauthn['publicKey']) || $process_webauthn['publicKey'] === false) { if (empty($process_webauthn['publicKey']) || $process_webauthn['publicKey'] === false) {
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
'type' => 'danger', 'type' => 'danger',
@ -1783,7 +1747,6 @@ function verify_tfa_login($username, $_data) {
return false; return false;
} }
// try verify authenticator
try { try {
$WebAuthn->processGet($clientDataJSON, $authenticatorData, $signature, $process_webauthn['publicKey'], $challenge, null, $GLOBALS['WEBAUTHN_UV_FLAG_LOGIN'], $GLOBALS['WEBAUTHN_USER_PRESENT_FLAG']); $WebAuthn->processGet($clientDataJSON, $authenticatorData, $signature, $process_webauthn['publicKey'], $challenge, null, $GLOBALS['WEBAUTHN_UV_FLAG_LOGIN'], $GLOBALS['WEBAUTHN_USER_PRESENT_FLAG']);
} }
@ -1796,44 +1759,22 @@ function verify_tfa_login($username, $_data) {
return false; return false;
} }
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_progress'),
'msg' => 'authenticator verified, check user role'
);
// if verified, check user role
$stmt = $pdo->prepare("SELECT `superadmin` FROM `admin` WHERE `username` = :username"); $stmt = $pdo->prepare("SELECT `superadmin` FROM `admin` WHERE `username` = :username");
$stmt->execute(array(':username' => $process_webauthn['username'])); $stmt->execute(array(':username' => $process_webauthn['username']));
$obj_props = $stmt->fetch(PDO::FETCH_ASSOC); $obj_props = $stmt->fetch(PDO::FETCH_ASSOC);
if ($obj_props['superadmin'] === 1) { if ($obj_props['superadmin'] === 1) {
// is admin
$_SESSION["mailcow_cc_role"] = "admin"; $_SESSION["mailcow_cc_role"] = "admin";
} }
elseif ($obj_props['superadmin'] === 0) { elseif ($obj_props['superadmin'] === 0) {
// is domainadmin
$_SESSION["mailcow_cc_role"] = "domainadmin"; $_SESSION["mailcow_cc_role"] = "domainadmin";
} }
else { else {
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_progress'),
'msg' => 'no admin or domainadmin role, check if normal user'
);
// no admin, check if normal user
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :username"); $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(':username' => $process_webauthn['username'])); $stmt->execute(array(':username' => $process_webauthn['username']));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($row['username'])) { if (!empty($row['username'])) {
// is user
$_SESSION["mailcow_cc_role"] = "user"; $_SESSION["mailcow_cc_role"] = "user";
} else { } else {
// err, no specific role found
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
'type' => 'danger', 'type' => 'danger',
'log' => array(__FUNCTION__, $username, '*'), 'log' => array(__FUNCTION__, $username, '*'),
@ -1843,7 +1784,6 @@ function verify_tfa_login($username, $_data) {
} }
} }
// check if fetched user and pendig_user matches
if ($process_webauthn['username'] != $_SESSION['pending_mailcow_cc_username']){ if ($process_webauthn['username'] != $_SESSION['pending_mailcow_cc_username']){
$_SESSION['return'][] = array( $_SESSION['return'][] = array(
'type' => 'danger', 'type' => 'danger',
@ -1853,15 +1793,6 @@ function verify_tfa_login($username, $_data) {
return false; return false;
} }
// just for debugging
// remove later
$_SESSION['return'][] = array(
'type' => 'info',
'log' => array(__FUNCTION__, 'tfa_success'),
'msg' => 'tfa flow success'
);
// set user session data and delete WebAuthn challenge session
$_SESSION["mailcow_cc_username"] = $process_webauthn['username']; $_SESSION["mailcow_cc_username"] = $process_webauthn['username'];
$_SESSION['tfa_id'] = $process_webauthn['id']; $_SESSION['tfa_id'] = $process_webauthn['id'];
$_SESSION['authReq'] = null; $_SESSION['authReq'] = null;