_ = XLATOR.gettext
ngettext = XLATOR.ngettext
-__version__ = '0.2.1'
+__version__ = '0.3.0'
# =============================================================================
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__(
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():
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]
# =============================================================================