FreddleSpl0it 6 месяцев назад
Родитель
Сommit
bc21e7fe50

+ 76 - 0
data/web/inc/functions.inc.php

@@ -1250,6 +1250,7 @@ function set_tfa($_data) {
 }
 }
 function fido2($_data) {
 function fido2($_data) {
   global $pdo;
   global $pdo;
+  global $WebAuthn;
   $_data_log = $_data;
   $_data_log = $_data;
   // Not logging registration data, only actions
   // Not logging registration data, only actions
   // Silent errors for "get" requests
   // Silent errors for "get" requests
@@ -1383,6 +1384,81 @@ function fido2($_data) {
         'msg' => array('object_modified', htmlspecialchars($username))
         'msg' => array('object_modified', htmlspecialchars($username))
       );
       );
     break;
     break;
+    case "verify":
+      $tokenData = json_decode($_data['token']);
+      $clientDataJSON = base64_decode($tokenData->clientDataJSON);
+      $authenticatorData = base64_decode($tokenData->authenticatorData);
+      $signature = base64_decode($tokenData->signature);
+      $id = base64_decode($tokenData->id);
+      $challenge = $_SESSION['challenge'];
+      $process_fido2 = fido2(array("action" => "get_by_b64cid", "cid" => $tokenData->id));
+      if ($process_fido2['pub_key'] === false) {
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array("fido2_login", $_data['user'], $process_fido2['username']),
+          'msg' => "login_failed"
+        );
+        return false;
+      }
+      try {
+        $WebAuthn->processGet($clientDataJSON, $authenticatorData, $signature, $process_fido2['pub_key'], $challenge, null, $GLOBALS['FIDO2_UV_FLAG_LOGIN'], $GLOBALS['FIDO2_USER_PRESENT_FLAG']);
+      }
+      catch (Throwable $ex) {
+        unset($process_fido2);
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array("fido2_login", $_data['user'], $process_fido2['username'], $ex->getMessage()),
+          'msg' => "login_failed"
+        );
+        return false;
+      }
+      $return = new stdClass();
+      $return->success = true;
+      $stmt = $pdo->prepare("SELECT `superadmin` FROM `admin` WHERE `username` = :username");
+      $stmt->execute(array(':username' => $process_fido2['username']));
+      $obj_props = $stmt->fetch(PDO::FETCH_ASSOC);
+      if ($obj_props['superadmin'] === 1 && (!$_data['user'] || $_data['user'] == "admin")) {
+        $_SESSION["mailcow_cc_role"] = "admin";
+      }
+      elseif ($obj_props['superadmin'] === 0 && (!$_data['user'] || $_data['user'] == "domainadmin")) {
+        $_SESSION["mailcow_cc_role"] = "domainadmin";
+      }
+      elseif (!isset($obj_props['superadmin']) && (!$_data['user'] || $_data['user'] == "user")) {
+        $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :username");
+        $stmt->execute(array(':username' => $process_fido2['username']));
+        $row = $stmt->fetch(PDO::FETCH_ASSOC);
+        if ($row['username'] == $process_fido2['username']) {
+          $_SESSION["mailcow_cc_role"] = "user";
+        }
+      }
+      else {
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array("fido2_login", $_data['user'], $process_fido2['username']),
+          'msg' => 'login_failed'
+        );
+        return false;
+      }
+      if (empty($_SESSION["mailcow_cc_role"])) {
+        session_unset();
+        session_destroy();
+        $_SESSION['return'][] =  array(
+          'type' => 'danger',
+          'log' => array("fido2_login", $_data['user'], $process_fido2['username']),
+          'msg' => 'login_failed'
+        );
+        return false;
+      }
+      $_SESSION["mailcow_cc_username"] = $process_fido2['username'];
+      $_SESSION["fido2_cid"] = $process_fido2['cid'];
+      unset($_SESSION["challenge"]);
+      $_SESSION['return'][] =  array(
+        'type' => 'success',
+        'log' => array("fido2_login", $_data['user'], $process_fido2['username']),
+        'msg' => array('logged_in_as', $process_fido2['username'])
+      );
+      return true;
+    break;
   }
   }
 }
 }
 function unset_tfa_key($_data) {
 function unset_tfa_key($_data) {

+ 8 - 0
data/web/inc/triggers.admin.inc.php

@@ -18,6 +18,14 @@ if (isset($_POST["verify_tfa_login"])) {
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_tfa_methods']);
   unset($_SESSION['pending_tfa_methods']);
 }
 }
+if (isset($_POST["verify_fido2_login"])) {
+  fido2(array(
+    "action" => "verify",
+    "token" => $_POST["token"],
+    "user" => "admin"
+  ));
+  exit;
+}
 
 
 if (isset($_GET["cancel_tfa_login"])) {
 if (isset($_GET["cancel_tfa_login"])) {
   unset($_SESSION['pending_pw_reset_token']);
   unset($_SESSION['pending_pw_reset_token']);

+ 8 - 0
data/web/inc/triggers.domainadmin.inc.php

@@ -29,6 +29,14 @@ if (isset($_POST["verify_tfa_login"])) {
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_tfa_methods']);
   unset($_SESSION['pending_tfa_methods']);
 }
 }
+if (isset($_POST["verify_fido2_login"])) {
+  fido2(array(
+    "action" => "verify",
+    "token" => $_POST["token"],
+    "user" => "domainadmin"
+  ));
+  exit;
+}
 
 
 if (isset($_GET["cancel_tfa_login"])) {
 if (isset($_GET["cancel_tfa_login"])) {
   unset($_SESSION['pending_pw_reset_token']);
   unset($_SESSION['pending_pw_reset_token']);

+ 8 - 0
data/web/inc/triggers.user.inc.php

@@ -83,6 +83,14 @@ if (isset($_POST["verify_tfa_login"])) {
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_mailcow_cc_role']);
   unset($_SESSION['pending_tfa_methods']);
   unset($_SESSION['pending_tfa_methods']);
 }
 }
+if (isset($_POST["verify_fido2_login"])) {
+  fido2(array(
+    "action" => "verify",
+    "token" => $_POST["token"],
+    "user" => "user"
+  ));
+  exit;
+}
 
 
 if (isset($_GET["cancel_tfa_login"])) {
 if (isset($_GET["cancel_tfa_login"])) {
   unset($_SESSION['pending_pw_reset_token']);
   unset($_SESSION['pending_pw_reset_token']);

+ 0 - 75
data/web/json_api.php

@@ -334,81 +334,6 @@ if (isset($_GET['query'])) {
           exit();
           exit();
       }
       }
     break;
     break;
-    case "process":
-      // only allow POST requests to process API endpoints
-      if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-        http_response_code(405);
-        echo json_encode(array(
-            'type' => 'error',
-            'msg' => 'only POST method is allowed'
-        ));
-        exit();
-      }
-      switch ($category) {
-        case "fido2-args":
-          header('Content-Type: application/json');
-          $post = trim(file_get_contents('php://input'));
-          if ($post) {
-            $post = json_decode($post);
-          }
-          $clientDataJSON = base64_decode($post->clientDataJSON);
-          $authenticatorData = base64_decode($post->authenticatorData);
-          $signature = base64_decode($post->signature);
-          $id = base64_decode($post->id);
-          $challenge = $_SESSION['challenge'];
-          $process_fido2 = fido2(array("action" => "get_by_b64cid", "cid" => $post->id));
-          if ($process_fido2['pub_key'] === false) {
-            $return = new stdClass();
-            $return->success = false;
-            echo json_encode($return);
-            exit;
-          }
-          try {
-            $WebAuthn->processGet($clientDataJSON, $authenticatorData, $signature, $process_fido2['pub_key'], $challenge, null, $GLOBALS['FIDO2_UV_FLAG_LOGIN'], $GLOBALS['FIDO2_USER_PRESENT_FLAG']);
-          }
-          catch (Throwable $ex) {
-            unset($process_fido2);
-            $return = new stdClass();
-            $return->success = false;
-            echo json_encode($return);
-            exit;
-          }
-          $return = new stdClass();
-          $return->success = true;
-          $stmt = $pdo->prepare("SELECT `superadmin` FROM `admin` WHERE `username` = :username");
-          $stmt->execute(array(':username' => $process_fido2['username']));
-          $obj_props = $stmt->fetch(PDO::FETCH_ASSOC);
-          if ($obj_props['superadmin'] === 1) {
-            $_SESSION["mailcow_cc_role"] = "admin";
-          }
-          elseif ($obj_props['superadmin'] === 0) {
-            $_SESSION["mailcow_cc_role"] = "domainadmin";
-          }
-          else {
-            $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :username");
-            $stmt->execute(array(':username' => $process_fido2['username']));
-            $row = $stmt->fetch(PDO::FETCH_ASSOC);
-            if ($row['username'] == $process_fido2['username']) {
-              $_SESSION["mailcow_cc_role"] = "user";
-            }
-          }
-          if (empty($_SESSION["mailcow_cc_role"])) {
-            session_unset();
-            session_destroy();
-            exit;
-          }
-          $_SESSION["mailcow_cc_username"] = $process_fido2['username'];
-          $_SESSION["fido2_cid"] = $process_fido2['cid'];
-          unset($_SESSION["challenge"]);
-          $_SESSION['return'][] =  array(
-            'type' => 'success',
-            'log' => array("fido2_login"),
-            'msg' => array('logged_in_as', $process_fido2['username'])
-          );
-          echo json_encode($return);
-        break;
-      }
-    break;
     case "get":
     case "get":
       function process_get_return($data, $object = true) {
       function process_get_return($data, $object = true) {
         if ($object === true) {
         if ($object === true) {

+ 7 - 9
data/web/templates/base.twig

@@ -391,16 +391,14 @@ function recursiveBase64StrToArrayBuffer(obj) {
         signature : cred.response.signature ? arrayBufferToBase64(cred.response.signature) : null
         signature : cred.response.signature ? arrayBufferToBase64(cred.response.signature) : null
       };
       };
     }).then(JSON.stringify).then(function(AuthenticatorAttestationResponse) {
     }).then(JSON.stringify).then(function(AuthenticatorAttestationResponse) {
-      return window.fetch("/api/v1/process/fido2-args", {method:'POST', body: AuthenticatorAttestationResponse, cache:'no-cache'});
+      var formData = new FormData();
+      formData.append("token", AuthenticatorAttestationResponse);
+      formData.append("verify_fido2_login", "true");
+
+      return window.fetch(window.location.href, {method:'POST', body: formData, cache:'no-cache'});
     }).then(function(response) {
     }).then(function(response) {
-      return response.json();
-    }).then(function(json) {
-      if (json.success) {
-        window.location = window.location.href.split("#")[0];
-  } else {
-    throw new Error();
-  }
-  }).catch(function(err) {
+      window.location = window.location.href.split("#")[0];
+    }).catch(function(err) {
     if (typeof err.message === 'undefined') {
     if (typeof err.message === 'undefined') {
       mailcow_alert_box(lang_fido2.fido2_validation_failed, "danger");
       mailcow_alert_box(lang_fido2.fido2_validation_failed, "danger");
     } else {
     } else {