+#
+# sshd.py
+#
+# Find number of ssh logins and authorised users
+#
+
+import re
+from systemd import journal
+
+from logparse.formatting import *
+from logparse.util import resolve
+from logparse import config
+
+import logging
+logger = logging.getLogger(__name__)
+
+def parse_log():
+
+ logger.debug("Starting sshd section")
+ section = Section("ssh")
+
+ j = journal.Reader()
+ j.this_boot()
+ j.log_level(journal.LOG_DEBUG)
+ j.add_match(_COMM="sshd")
+
+ messages = [entry["MESSAGE"] for entry in j if "MESSAGE" in entry]
+
+ login_data = Data("successful", [])
+ invalid_data = Data("invalid", [])
+ failed_data = Data("failed", [])
+
+ for msg in messages:
+
+ if "Accepted publickey" in msg:
+ entry = re.search('^.*publickey\sfor\s(\w*)\sfrom\s(\S*)', msg) # [('user', 'ip')]
+ user = entry.group(1)
+ ip = entry.group(2)
+
+ userhost = user + '@' + resolve(ip, fqdn=config.prefs['sshd']['resolve-domains'])
+ login_data.items.append(userhost)
+
+ elif "Connection closed by authenticating user root" in msg:
+ entry = re.search('^.*Connection closed by authenticating user (\S+) (\S+)', msg) # [('user', 'ip')]
+ user = entry.group(1)
+ ip = entry.group(2)
+
+ userhost = user + '@' + resolve(ip, fqdn=config.prefs['sshd']['resolve-domains'])
+ failed_data.items.append(userhost)
+
+ elif "Invalid user" in msg:
+ entry = re.search('^.*Invalid user (\S+) from (\S+).*', msg) # [('user', 'ip')]
+ user = entry.group(1)
+ ip = entry.group(2)
+
+ userhost = user + '@' + resolve(ip, fqdn=config.prefs['sshd']['resolve-domains'])
+ invalid_data.items.append(userhost)
+
+ login_data.subtitle = plural("successful login", len(login_data.items)) + " from"
+ login_data.orderbyfreq()
+ login_data.truncl(config.prefs['maxlist'])
+
+ invalid_data.subtitle = plural("attempted login", len(invalid_data.items))
+ invalid_data.orderbyfreq()
+ invalid_data.subtitle += plural(" from invalid user", len(invalid_data.items), False)
+ invalid_data.truncl(config.prefs['maxlist'])
+
+ failed_data.subtitle = plural("failed login", len(failed_data.items)) + " from"
+ failed_data.orderbyfreq()
+ failed_data.truncl(config.prefs['maxlist'])
+
+ section.append_data(login_data)
+ section.append_data(invalid_data)
+ section.append_data(failed_data)
+
+ logger.info("Finished sshd section")
+ return section