# # logactio - simple framework for doing configured action on certain # log file events # # Copyright 2012 - 2015 David Sommerseth # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, version 2 # of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # For the avoidance of doubt the "preferred form" of this code is one which # is in an open unpatent encumbered format. Where cryptographic key signing # forms part of the process of creating an executable the information # including keys needed to generate an equivalently functional executable # are deemed to be part of the source code. # import sys, smtplib from email.mime.text import MIMEText from LogActio import Message, ReporterQueue class SMTPreporter(ReporterQueue.ReporterQueue): """Simple LogActio reporter module, sending alerts via SMTP Example configuration to be used in /etc/logactio.cfg [Reporter:SMTP] module: SMTPreporter sender: logactio@example.com recipients: john.doe@example.com, jane.doe@example.com subject_prefix: LogActio Alert: smtp_host: localhost smtp_port: 25 This will send reports to the configured 'recipients' using the given SMTP server. """ def __init__(self, config, logger = None): if not config.has_key("sender"): raise Exception("SMTPreporter is not configured with a sender address") if not config.has_key("recipients"): raise Exception("SMTPreporter is not configured with any recipients") if not config.has_key("smtp_host"): raise Exception("SMTPreporter is not configured with SMTP host") self.__log = logger and logger or self.__logfnc self.__sender = config["sender"] self.__recipients = config["recipients"].split(",") self.__subjprefix = config.has_key("subject_prefix") and config["subject_prefix"] or None self.__smtphost = config["smtp_host"] self.__smtpport = config.has_key("smtp_port") and (int(config["smtp_port"])) or 25 self.__smtpuser = config.has_key("smtp_username") and config["smtp_username"] or None self.__smtppass = config.has_key("smtp_password") and config["smtp_password"] or None self.__sslmode = config.has_key("sslmode") and config["sslmode"] or None if (self.__smtpuser and not self.__smtppass) or (not self.__smtpuser and self.__smtppass): raise Exception("SMTPreporter must have both smtp_username and smtp_password") if self.__sslmode is not None and self.__sslmode != "SSL" and self.__sslmode != "STARTTLS": raise Exception("SMTPreporter accepts only SSL or STARTTLS as sslmode values") ReporterQueue.ReporterQueue.__init__(self, "SMTPreporter", "SMTP Reporter", self.__processqueue) def __logfnc(self, lvl, msg): print "%s" % msg sys.stdout.flush() def __processqueue(self): done = False # Process the message queue while not done: msg = self._QueueGet() if( msg.MessageType() == Message.MSG_SHUTDOWN ): # Prepare for shutdown done = True elif( msg.MessageType() == Message.MSG_SEND ): m = msg.Message() msg = MIMEText(m["body"]) msg["From"] = self.__sender msg["To"] = ",".join(self.__recipients) if self.__subjprefix is None: msg["Subject"] = "LogActio Alert: %s" % m["subject"] else: msg["Subject"] = "%s %s" % (self.__subjprefix, m["subject"]) try: self.__log(3, "[SMTPreporter] Connecting to %s:%i" % (self.__smtphost, self.__smtpport)) if self.__sslmode == "SSL": smtp.smtplib.SMTP_SSL(self.__smtphost, self.__smtpport) else: smtp = smtplib.SMTP(self.__smtphost, self.__smtpport) if self.__sslmode == "STARTTLS": smtp.starttls() if self.__smtpuser is not None: self.__log(3, "[SMTPreporter] Logging in as %s" % self.__smtpuser) smtp.login(self.__smtpuser, self.__smtppass) smtp.sendmail(self.__sender, self.__recipients, msg.as_string()) self.__log(1, "Report sent to: %s" % ", ".join(self.__recipients)) smtp.quit() except Exception, e: self.__log(0, "** ERROR ** SMTPreporter failed: %s" % str(e)) def ProcessEvent(self, logfile, prefix, msg, count, threshold): # Format the report message msg = {"subject": "Alerts from %s" % logfile, "body": """ LogActio have detected %s events in the %s log file since it started running.\n The following information was extracted:\n %s """ % (count, logfile, "\n".join(msg.split("|")))} # Queue the message for sending self._QueueMsg(0, msg) def InitReporter(config, logger = None): return SMTPreporter(config, logger)