]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Continue parsing with lib/pp_admintools/handler/pflogparse.py
authorFrank Brehm <frank.brehm@pixelpark.com>
Thu, 21 Mar 2024 16:36:31 +0000 (17:36 +0100)
committerFrank Brehm <frank.brehm@pixelpark.com>
Thu, 21 Mar 2024 16:36:31 +0000 (17:36 +0100)
lib/pp_admintools/handler/pflogparse.py

index fb9d0b90894f161c86c15b8b3307d472f9307cc8..aa03a881632b8dcd8f49b336ceba2cfb928fce44 100644 (file)
@@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__)
 _ = XLATOR.gettext
 ngettext = XLATOR.ngettext
 
-__version__ = '0.2.1'
+__version__ = '0.3.0'
 
 
 # =============================================================================
@@ -65,7 +65,7 @@ class PostfixLogfileParser(HandlingObject):
             simulate=False, force=False, assumed_answer=None,
             terminal_has_colors=False, initialized=False):
         """Initialize the PostfixLogfileParser object."""
-        self.chains = {}
+        self.chain = {}
         self.active_smtpd_pid = {}
 
         super(PostfixLogfileParser, self).__init__(
@@ -88,12 +88,12 @@ class PostfixLogfileParser(HandlingObject):
         else:
             LOG.warn(msg)
 
-        self.chains = {}
+        self.chain = {}
         self.active_smtpd_pid = {}
 
     # -------------------------------------------------------------------------
     def parse(self, fh):
-        """Parse the content of a given logfile and store the results in self.chains."""
+        """Parse the content of a given logfile and store the results in self.chain."""
         LOG.debug(_('Start parsing postfix logfile ...'))
 
         for line in fh.readlines():
@@ -118,33 +118,119 @@ class PostfixLogfileParser(HandlingObject):
             postfix_id = m_id['id'].upper()
             message = self.re_postfix_id.sub('', message)
 
+        entry = {
+            'timestamp': timestamp,
+            'host': host,
+            'command': command,
+            'pid': pid,
+            'message': message,
+            'postfix_id': postfix_id,
+        }
         if self.verbose > 3:
-            entry = {
-                'timestamp': timestamp,
-                'command': command,
-                'pid': pid,
-                'postfix_id': postfix_id,
-                'message': message,
-            }
             LOG.debug('Found log entry:\n' + pp(entry))
 
         if command == 'postfix/smtpd' and pid:
-            m_conn = self.re_connect.search(message)
-            if m_conn:
-                chain = PostfixLogchainInfo(
-                    client_host=m_conn['client'],
-                    client_addr=m_conn['addr'],
-                    start=timestamp,
-                    postfix_id=postfix_id,
-                    smtpd_pid=pid,
-                    mailhost=host,
-                )
-                self.active_smtpd_pid[pid] = chain
-
-                if self.verbose > 3:
-                    msg = 'Creating Postfix log chain:\n' + pp(chain.as_dict())
-                    LOG.debug(msg)
-                return
+            self.eval_smtpd_line(entry)
+            return
+
+        if postfix_id:
+            if command == 'postfix/smtpd' and pid:
+                if postfix_id not in self.chain and pid in self.active_smtpd_pid \
+                        and self.active_smtpd_pid[pid]:
+                    self.chain[postfix_id] = self.active_smtpd_pid[pid]
+
+            if pid in self.active_smtpd_pid and self.active_smtpd_pid[pid] \
+                    and postfix_id in self.chain:
+                m = self.re_message_id.search(message)
+                if m:
+                    self.chain[postfix_id].message_id = m[1]
+                    return
+
+            m = self.re_from_addr.match(message)
+            if m and postfix_id in self.chain and self.chain[postfix_id]:
+                self.logchain[postfix_id].from_address = m[1]
+
+    # -------------------------------------------------------------------------
+    def eval_smtpd_line(self, entry):
+        """Evaluate a log line from comman postfix/smtpd."""
+        pid = entry['pid']
+        message = entry['message']
+        timestamp = entry['timestamp']
+        m_conn = self.re_connect.search(message)
+
+        if m_conn:
+            chain = PostfixLogchainInfo(
+                client_host=m_conn['client'],
+                client_addr=m_conn['addr'],
+                start=entry['timestamp'],
+                postfix_id=entry['postfix_id'],
+                smtpd_pid=pid,
+                mailhost=entry['host'],
+            )
+            self.active_smtpd_pid[pid] = chain
+
+            if self.verbose > 3:
+                msg = 'Creating Postfix log chain:\n' + pp(chain.as_dict())
+                LOG.debug(msg)
+
+            return
+
+        m_dis = self.re_disconnect.search(message)
+        if m_dis:
+            if self.verbose > 3:
+                LOG.debug('Found disconnection for PID {}: '.format(pid) + message)
+            if pid in self.active_smtpd_pid:
+                self.evaluate_disconnect(message, timestamp, pid)
+                if self.verbose > 2:
+                    LOG.debug(
+                        'Updated PD struct of {}:\n'.format(pid) + pp(self.active_smtpd_pid[pid]))
+                del self.active_smtpd_pid[pid]
+
+            return
+
+    # -------------------------------------------------------------------------
+    def evaluate_disconnect(self, message, timestamp, pid):
+        """Evaluate a disconnect line of smtptd."""
+        if pid not in self.active_smtpd_pid:
+            return
+        if not self.active_smtpd_pid[pid]:
+            return
+        if not self.active_smtpd_pid[pid].postfix_id:
+            return
+
+        postfix_id = self.active_smtpd_pid[pid].postfix_id
+        if not self.chain[postfix_id]:
+            return
+
+        self.chain[postfix_id].end = timestamp
+
+        m = self.re_dis_ehlo.search(message)
+        if m:
+            self.chain[postfix_id].ehlo = m[1]
+
+        m = self.re_dis_quit.search(message)
+        if m:
+            self.chain[postfix_id].quit = m[1]
+
+        m = self.re_dis_auth.search(message)
+        if m:
+            self.chain[postfix_id].auth = m[1]
+
+        m = self.re_dis_commands.search(message)
+        if m:
+            self.chain[postfix_id].commands = m[1]
+
+        m = self.re_dis_rcpt.search(message)
+        if m:
+            self.chain[postfix_id].rcpt = m[1]
+
+        m = self.re_dis_data.search(message)
+        if m:
+            self.chain[postfix_id].data = m[1]
+
+        m = self.re_dis_mail.search(message)
+        if m:
+            self.chain[postfix_id].mail = m[1]
 
 
 # =============================================================================