Browse Source

Fix sasl_logs

FreddleSpl0it 5 tháng trước cách đây
mục cha
commit
805634f9a9

+ 10 - 5
data/conf/dovecot/auth/mailcowauth.php

@@ -69,29 +69,34 @@ require_once 'functions.acl.inc.php';
 
 $isSOGoRequest = $post['real_rip'] == getenv('IPV4_NETWORK') . '.248';
 $result = false;
-$protocol = $post['protocol'];
 if ($isSOGoRequest) {
-  $protocol = null;
   // This is a SOGo Auth request. First check for SSO password.
   $sogo_sso_pass = file_get_contents("/etc/sogo-sso/sogo-sso.pass");
   if ($sogo_sso_pass === $post['password']){
     error_log('MAILCOWAUTH: SOGo SSO auth for user ' . $post['username']);
+    set_sasl_log($post['username'], $post['real_rip'], "SOGO");
     $result = true;
   }
 }
 if ($result === false){
-  $result = apppass_login($post['username'], $post['password'], $protocol, array(
+  $result = apppass_login($post['username'], $post['password'], array($post['service'] => true), array(
     'is_internal' => true,
     'remote_addr' => $post['real_rip']
   ));
-  if ($result) error_log('MAILCOWAUTH: App auth for user ' . $post['username']);
+  if ($result) {
+    error_log('MAILCOWAUTH: App auth for user ' . $post['username']);
+    set_sasl_log($post['username'], $post['real_rip'], $post['service']);
+  }
 }
 if ($result === false){
   // Init Identity Provider
   $iam_provider = identity_provider('init');
   $iam_settings = identity_provider('get');
   $result = user_login($post['username'], $post['password'], array('is_internal' => true));
-  if ($result) error_log('MAILCOWAUTH: User auth for user ' . $post['username']);
+  if ($result) {
+    error_log('MAILCOWAUTH: User auth for user ' . $post['username']);
+    set_sasl_log($post['username'], $post['real_rip'], $post['service']);
+  }
 }
 
 if ($result) {

+ 4 - 5
data/conf/dovecot/auth/passwd-verify.lua

@@ -12,12 +12,11 @@ function auth_password_verify(request, password)
     username = request.user,
     password = password,
     real_rip = request.real_rip,
-    protocol = {}
+    service = request.service
   }
-  req.protocol[request.service] = true
   local req_json = json.encode(req)
-  local res = {} 
-  
+  local res = {}
+
   local b, c = https.request {
     method = "POST",
     url = "https://nginx:9082",
@@ -33,7 +32,7 @@ function auth_password_verify(request, password)
   if api_response.success == true then
     return dovecot.auth.PASSDB_RESULT_OK, ""
   end
-  
+
   return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Failed to authenticate"
 end
 

+ 31 - 19
data/web/inc/functions.auth.inc.php

@@ -9,25 +9,51 @@ function check_login($user, $pass, $app_passwd_data = false, $extra = null) {
   // Try validate admin
   if (!isset($role) || $role == "admin") {
     $result = admin_login($user, $pass);
-    if ($result !== false) return $result;
+    if ($result !== false){
+      return $result;
+    }
   }
 
   // Try validate domain admin
   if (!isset($role) || $role == "domain_admin") {
     $result = domainadmin_login($user, $pass);
-    if ($result !== false) return $result;
+    if ($result !== false) {
+      return $result;
+    }
   }
 
   // Try validate user
   if (!isset($role) || $role == "user") {
     $result = user_login($user, $pass);
-    if ($result !== false) return $result;
+    if ($result !== false) {
+      if ($app_passwd_data['eas'] === true) {
+        $service = 'EAS';
+      } elseif ($app_passwd_data['dav'] === true) {
+        $service = 'DAV';
+      } else {
+        $service = 'MAILCOWUI';
+      }
+      $real_rip = ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']);
+      set_sasl_log($user, $real_rip, $service);
+      return $result;
+    }
   }
 
   // Try validate app password
   if (!isset($role) || $role == "app") {
     $result = apppass_login($user, $pass, $app_passwd_data);
-    if ($result !== false) return $result;
+    if ($result !== false) {
+      if ($app_passwd_data['eas'] === true) {
+        $service = 'EAS';
+      } elseif ($app_passwd_data['dav'] === true) {
+        $service = 'DAV';
+      } else {
+        $service = 'NONE';
+      }
+      $real_rip = ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']);
+      set_sasl_log($user, $real_rip, $service, $pass);
+      return $result;
+    }
   }
 
   // skip log and only return false if it's an internal request
@@ -415,21 +441,7 @@ function apppass_login($user, $pass, $app_passwd_data, $extra = null){
 
     // verify password
     if (verify_hash($row['password'], $pass) !== false) {
-      if ($is_internal){
-        $remote_addr = $extra['remote_addr'];
-      } else {
-        $remote_addr = ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']);
-      }
-
-      $service = strtoupper($is_app_passwd);
-      $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' => $remote_addr
-      ));
-
+      $_SESSION['app_passwd_id'] = $row['app_passwd_id'];
       unset($_SESSION['ldelay']);
       return "user";
     }

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

@@ -350,6 +350,34 @@ function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
   }
 
 }
+function set_sasl_log($username, $real_rip, $service){
+  global $pdo;
+
+  try {
+    if (!empty($_SESSION['app_passwd_id'])) {
+      $app_password = $_SESSION['app_passwd_id'];
+    } else {
+      $app_password = 0;
+    }
+
+    $stmt = $pdo->prepare('REPLACE INTO `sasl_log` (`username`, `real_rip`, `service`, `app_password`) VALUES (:username, :real_rip, :service, :app_password)');
+    $stmt->execute(array(
+      ':username' => $username,
+      ':real_rip' => $real_rip,
+      ':service' => $service,
+      ':app_password' => $app_password
+    ));
+  } catch (PDOException $e) {
+    $_SESSION['return'][] =  array(
+      'type' => 'danger',
+      'log' => array(__FUNCTION__, $_data_log),
+      'msg' => array('mysql_error', $e)
+    );
+    return false;
+  }
+
+  return true;
+}
 function flush_memcached() {
   try {
     $m = new Memcached();

+ 0 - 6
data/web/js/site/user.js

@@ -90,13 +90,7 @@ jQuery(function($){
           console.log('error reading last logins');
         },
         success: function (data) {
-          $('.last-ui-login').html('');
           $('.last-sasl-login').html('');
-          if (data.ui.time) {
-            $('.last-ui-login').html('<i class="bi bi-person-fill"></i> ' + lang.last_ui_login + ': ' + unix_time_format(data.ui.time));
-          } else {
-            $('.last-ui-login').text(lang.no_last_login);
-          }
           if (data.sasl) {
             $('.last-sasl-login').append('<ul class="list-group">');
             $.each(data.sasl, function (i, item) {

+ 1 - 2
data/web/templates/user/tab-user-auth.twig

@@ -184,7 +184,7 @@
           </div>
           {% endif %}
         </div>
-        <div class="ms-auto col-xl-3 col-lg-5 col-md-12 col-12 d-flex flex-column well flex-grow-1">
+        <div class="ms-auto col-xl-3 col-lg-5 col-md-12 col-12 d-flex flex-column well flex-grow-1" id="recent-logins">
           <legend class="d-flex">
             <span>{{ lang.user.recent_successful_connections }}</span>
             <div id="spinner-last-login" class="ms-auto my-auto spinner-border spinner-border-sm d-none" role="status">
@@ -192,7 +192,6 @@
             </div>
           </legend>
           <hr>
-          <h6 class="last-ui-login"></h6>
           <div class="d-flex">
             <span class="clear-last-logins mt-auto mb-2">
               {{ lang.user.clear_recent_successful_connections }}