Browse Source

[Postfix, Web] Feature: Show last SMTP login

andryyy 5 years ago
parent
commit
1f36ae28d4

+ 3 - 0
data/Dockerfiles/postfix/Dockerfile

@@ -25,6 +25,7 @@ RUN groupadd -g 102 postfix \
 	postfix \
 	postfix-mysql \
 	postfix-pcre \
+	redis-tools \
 	sasl2-bin \
 	sudo \
 	supervisor \
@@ -44,6 +45,7 @@ COPY postfix.sh /opt/postfix.sh
 COPY rspamd-pipe-ham /usr/local/bin/rspamd-pipe-ham
 COPY rspamd-pipe-spam /usr/local/bin/rspamd-pipe-spam
 COPY whitelist_forwardinghosts.sh /usr/local/bin/whitelist_forwardinghosts.sh
+COPY smtpd_last_login.sh /usr/local/bin/smtpd_last_login.sh
 COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh
 COPY docker-entrypoint.sh /docker-entrypoint.sh
 
@@ -51,6 +53,7 @@ RUN chmod +x /opt/postfix.sh \
   /usr/local/bin/rspamd-pipe-ham \
   /usr/local/bin/rspamd-pipe-spam \
   /usr/local/bin/whitelist_forwardinghosts.sh \
+  /usr/local/bin/smtpd_last_login.sh \
   /usr/local/sbin/stop-supervisor.sh
 RUN rm -rf /tmp/* /var/tmp/*
 

+ 20 - 0
data/Dockerfiles/postfix/smtpd_last_login.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Do not attempt to write to slave
+if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
+  REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
+else
+  REDIS_CMDLINE="redis-cli -h redis -p 6379"
+fi
+
+while read QUERY; do
+  QUERY=($QUERY)
+  # If nothing matched, end here - Postfix last line will be empty
+  if [[ -z "$(echo ${QUERY[0]} | tr -d '\040\011\012\015')" ]]; then
+    echo -ne "action=dunno\n\n"
+  # We found a username, log and return
+  elif [[ "${QUERY[0]}" =~ sasl_username ]]; then
+    ${REDIS_CMDLINE} SET "last-login/smtp/$(echo ${QUERY[0]#sasl_username=})" "$(date +%s)"
+    echo -ne "action=dunno\n\n"
+  fi
+done

+ 1 - 0
data/conf/postfix/main.cf

@@ -189,6 +189,7 @@ smtp_sasl_auth_soft_bounce = no
 postscreen_discard_ehlo_keywords = silent-discard, dsn
 compatibility_level = 2
 smtputf8_enable = no
+smtpd_last_auth = check_policy_service inet:127.0.0.1:10028
 # Define protocols for SMTPS and submission service
 submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
 smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

+ 7 - 1
data/conf/postfix/master.cf

@@ -16,6 +16,7 @@ smtps    inet  n       -       n       -       -       smtpd
   -o smtpd_tls_mandatory_protocols=$smtps_smtpd_tls_mandatory_protocols
   -o tls_preempt_cipherlist=yes
   -o syslog_name=postfix/smtps
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 10465    inet  n       -       n       -       -       smtpd
   -o smtpd_upstream_proxy_protocol=haproxy
   -o smtpd_tls_wrappermode=yes
@@ -23,6 +24,7 @@ smtps    inet  n       -       n       -       -       smtpd
   -o smtpd_tls_mandatory_protocols=$smtps_smtpd_tls_mandatory_protocols
   -o tls_preempt_cipherlist=yes
   -o syslog_name=postfix/smtps-haproxy
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 
 # smtpd with starttls on 587/tcp
 # TLS protocol can be modified by setting submission_smtpd_tls_mandatory_protocols in extra.cf
@@ -33,6 +35,7 @@ submission inet n       -       n       -       -       smtpd
   -o smtpd_tls_mandatory_protocols=$submission_smtpd_tls_mandatory_protocols
   -o tls_preempt_cipherlist=yes
   -o syslog_name=postfix/submission
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 10587      inet n       -       n       -       -       smtpd
   -o smtpd_upstream_proxy_protocol=haproxy
   -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
@@ -41,6 +44,7 @@ submission inet n       -       n       -       -       smtpd
   -o smtpd_tls_mandatory_protocols=$submission_smtpd_tls_mandatory_protocols
   -o tls_preempt_cipherlist=yes
   -o syslog_name=postfix/submission-haproxy
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 
 # used by SOGo
 # smtpd_sender_restrictions should match main.cf, but with check_sasl_access prepended for login-as-mailbox-user function
@@ -49,6 +53,7 @@ submission inet n       -       n       -       -       smtpd
   -o smtpd_tls_auth_only=no
   -o smtpd_sender_restrictions=check_sasl_access,regexp:/opt/postfix/conf/allow_mailcow_local.regexp,reject_authenticated_sender_login_mismatch,permit_mynetworks,permit_sasl_authenticated,reject_unlisted_sender,reject_unknown_sender_domain
   -o syslog_name=postfix/sogo
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 
 # used to reinject quarantine mails
 590 inet n      -       n       -       -       smtpd
@@ -58,13 +63,13 @@ submission inet n       -       n       -       -       smtpd
   -o smtpd_milters=
   -o non_smtpd_milters=
   -o syslog_name=postfix/quarantine
+  -o smtpd_end_of_data_restrictions=$smtpd_last_auth
 
 # enforced smtp connector
 smtp_enforced_tls      unix  -       -       n       -       -       smtp
   -o smtp_tls_security_level=encrypt
   -o syslog_name=enforced-tls-smtp
   -o smtp_delivery_status_filter=pcre:/opt/postfix/conf/smtp_dsn_filter
-
 # smtp connector used, when a transport map matched
 # this helps to have different sasl maps than we have with sender dependent transport maps
 smtp_via_transport_maps      unix  -       -       n       -       -       smtp
@@ -100,6 +105,7 @@ maildrop   unix  -       n       n       -       -       pipe flags=DRhu
 
 # start whitelist_fwd
 127.0.0.1:10027 inet n n n - 0 spawn user=nobody argv=/usr/local/bin/whitelist_forwardinghosts.sh
+127.0.0.1:10028 inet n n n - 0 spawn user=nobody argv=/usr/local/bin/smtpd_last_login.sh
 # end whitelist_fwd
 
 # start watchdog-specific

+ 9 - 3
data/web/css/site/mailbox.css

@@ -57,7 +57,13 @@ table tbody tr {
 table tbody tr td input[type="checkbox"] {
   cursor: pointer;
 }
-.label-last {
-  color: #c7254e !important;
-  background-color: #f9f2f4 !important;
+.label-last-in {
+  line-height: 2.5;
+  color: #4a4a4a!important;
+  background-color: #ececec!important;
+}
+.label-last-out {
+  line-height: 2.5;
+  color: #ececec!important;
+  background-color: #a0a0a0!important;
 }

+ 5 - 0
data/web/inc/functions.mailbox.inc.php

@@ -3345,10 +3345,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
           $mailboxdata = array();
           $rl = ratelimit('get', 'mailbox', $_data);
           $last_imap_login = $redis->Get('last-login/imap/' . $_data);
+          $last_smtp_login = $redis->Get('last-login/smtp/' . $_data);
           $last_pop3_login = $redis->Get('last-login/pop3/' . $_data);
           if ($last_imap_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
             $last_imap_login = '0';
           }
+          if ($last_smtp_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
+            $last_smtp_login = '0';
+          }
           if ($last_pop3_login === false || $GLOBALS['SHOW_LAST_LOGIN'] === false) {
             $last_pop3_login = '0';
           }
@@ -3416,6 +3420,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
           $mailboxdata['is_relayed'] = $row['backupmx'];
           $mailboxdata['name'] = $row['name'];
           $mailboxdata['last_imap_login'] = $last_imap_login;
+          $mailboxdata['last_smtp_login'] = $last_smtp_login;
           $mailboxdata['last_pop3_login'] = $last_pop3_login;
           $mailboxdata['active'] = $row['active'];
           $mailboxdata['active_int'] = $row['active_int'];

+ 4 - 3
data/web/js/site/mailbox.js

@@ -363,8 +363,9 @@ jQuery(function($){
         },
         "formatter": function(value){
           res = value.split("/");
-          return '<div class="label label-last">IMAP @ ' + unix_time_format(Number(res[0])) + '</div> ' +
-            '<div class="label label-last">POP3 @ ' + unix_time_format(Number(res[1])) + '</div>';
+          return '<div class="label label-last-in">IMAP @ ' + unix_time_format(Number(res[0])) + '</div><br>' +
+            '<div class="label label-last-in">POP3 @ ' + unix_time_format(Number(res[1])) + '</div><br>' + 
+            '<div class="label label-last-out">SMTP @ ' + unix_time_format(Number(res[2])) + '</div>';
         }},
         {"name":"quarantine_notification","filterable": false,"title":lang.quarantine_notification,"breakpoints":"all"},
         {"name":"in_use","filterable": false,"type":"html","title":lang.in_use,"sortValue": function(value){
@@ -388,7 +389,7 @@ jQuery(function($){
           $.each(data, function (i, item) {
             item.quota = item.quota_used + "/" + item.quota;
             item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
-            item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login;
+            item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login + '/' + item.last_smtp_login;
             if (!item.rl) {
               item.rl = '∞';
             } else {