# as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from datetime import datetime import pytz from ail import Profile from ail.services.ssh import SSHService from ail.util import adjust_time, make_container, make_to_xml logger = logging.getLogger(__name__) Login = make_container('Login', ('source', 'source_port', 'user', 'timestamp', 'process', 'reason')) class FailedLogins(object): """Expected output: :: -0600 Mar 2 06:17:33 anbox sshd[5379]: Failed password for invalid user 0 from 74.63.242.122 port 47742 ssh2 Mar 2 06:04:23 anbox sshd[4764]: Failed password for invalid user music from 37.187.57.167 port 51552 ssh2 Mar 2 05:47:56 anbox sshd[3986]: Failed password for invalid user music from 37.187.57.167 port 37677 ssh2 Mar 2 04:58:32 anbox sshd[1594]: Failed password for invalid user music from 37.187.57.167 port 52513 ssh2 Mar 2 04:42:03 anbox sshd[801]: Failed password for invalid user music from 37.187.57.167 port 38633 ssh2 """ def __init__(self, output): self._logins = {} self._to_xml = make_to_xml(())
# This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = "jdmorts" import logging from datetime import datetime, timedelta from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container logger = logging.getLogger(__name__) User = make_container("User", ("username", "password", "last_password_change")) class Users(object): """Parse the Linux shadow file. The shadow struct contains the following: :: sp_namp - pointer to null-terminated user name sp_pwdp - pointer to null-terminated password sp_lstchg - days since Jan 1, 1970 password was last changed sp_min - days before which password may not be changed sp_max - days after which password must be changed sp_warn - days before password is to expire that user is warned of pending password expiration sp_inact - days after password expires that account is considered inactive and disabled sp_expire - days since Jan 1, 1970 when account will be disabled sp_flag - reserved for future use
# as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from datetime import datetime import pytz from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container, adjust_time logger = logging.getLogger(__name__) Process = make_container('Process', ('pid', 'ppid', 'cpu', 'mem', 'stat', 'started', 'time', 'user', 'command')) class Processes(object): """Expected output: :: -0600 PID PPID %CPU %MEM STAT STARTED TIME USER COMMAND 1 0 0.0 0.0 Ss Wed Nov 20 20:57:35 2013 00:01:52 root init [3] 2 0 0.0 0.0 S Wed Nov 20 20:57:35 2013 00:00:00 root [kthreadd] 3 2 0.0 0.0 S Wed Nov 20 20:57:35 2013 00:00:04 root [ksoftirqd/0] 4 2 0.0 0.0 S Wed Nov 20 20:57:35 2013 00:01:29 root [kworker/0:0] . . . 1970 1 1.4 5.7 Sl Tue Nov 26 22:12:17 2013 1-05:02:42 rabbitmq /usr/... . . .
# This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container logger = logging.getLogger(__name__) Netstat = make_container('Netstat', ('proto', 'local_address', 'local_port', 'foreign_address', 'foreign_port', 'state', 'program')) class Netstats(object): """Expected output: :: Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 1606/inetd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 7611/sshd . . . udp6 0 0 :::123 :::* 8348/ntpd udp6 0 0 ::1:45788 ::1:45788 ESTABLISHED 1738/postgres """ def __init__(self, output):
# Copyright © 2014 Jean des Morts <*****@*****.**> # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container logger = logging.getLogger(__name__) Package = make_container('Package', ('package', 'version')) class Packages(object): """Example output: :: GConf2.i386 2.14.0-9.el5 GConf2.x86_64 2.14.0-9.el5 GConf2-devel.x86_64 2.14.0-9.el5 ImageMagick.i386 ImageMagick.x86_64 6.2.8.0-15.el5_8 """ def __init__(self, output): self._packages = [] self._to_xml = make_to_xml(())
# Copyright © 2014 Jean des Morts <*****@*****.**> # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container logger = logging.getLogger(__name__) User = make_container('User', ('username',)) class ActiveUsers(object): """ """ def __init__(self, output): self._active_users = {} self._to_xml = make_to_xml(()) try: for user in (User(u) for u in output[0].strip().split(' ') if u): self._active_users[user.username] = user except IndexError: raise ValueError('Unable to initialize ActiveUsers object')
# Copyright © 2014 Jean des Morts <*****@*****.**> # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The F**k You Want To Public License, Version 2, # as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container logger = logging.getLogger(__name__) Mount = make_container('Mount', ('fs_spec', 'fs_file', 'fs_vfstype', 'fs_mntops')) class Mounts(object): """Expected format: /dev/mapper/VolGroup00-LogVol00 on / type ext3 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) /dev/hda1 on /boot type ext3 (rw) tmpfs on /dev/shm type tmpfs (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw) //10.0.5.190/XMLImport on /mnt/winmnt type cifs (rw,mand) """ def __init__(self, output):
# as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from datetime import datetime import pytz from ail import Profile from ail.services.ssh import SSHService from ail.util import adjust_time, make_container, make_to_xml logger = logging.getLogger(__name__) Log = make_container('Log', ('user', 'timestamp', 'tty', 'pwd', 'pseudo', 'command')) class SudoLogs(object): """Expected output: :: -0600 Feb 10 13:46:49 anbox sudo: anuser : TTY=pts/0 ; PWD=/home/anuser/dev/working ; USER=root ; COMMAND=/usr/bin/tail -f /var/log/cron Feb 10 18:12:11 anbox sudo: anuser : TTY=pts/0 ; PWD=/home/anuser/dev/working ; USER=root ; COMMAND=/etc/rc.d/rc.ntpd status Feb 10 19:48:16 anbox sudo: anuser : TTY=pts/0 ; PWD=/home/anuser/dev/working ; USER=root ; COMMAND=/usr/bin/grep 24709 /var/log/cron Feb 10 19:48:23 anbox sudo: anuser : TTY=pts/0 ; PWD=/home/anuser/dev/working ; USER=root ; COMMAND=/usr/bin/tail /var/log/cron . . . (the next one fails, presently) Feb 27 12:10:30 ica-valinux-02 sudo: pam_unix(sudo:auth): conversation failed . . . Mar 10 19:58:02 anbox sudo: anuser : a password is required ; TTY=pts/2 ; PWD=/home/anuser ; USER=root ; COMMAND=/usr/bin/cat /var/log/secure /var/log/secure.1 /var/log/secure.2 /var/log/secure.3 /var/log/secure.4 """
# as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' import logging from datetime import datetime import pytz from ail import Profile from ail.services.ssh import SSHService from ail.util import make_to_xml, make_container, adjust_time logger = logging.getLogger(__name__) Login = make_container('Login', ('username', 'tty', 'timestamp', 'duration', 'source')) class Logins(object): """Parse output from the 'last' command, which parses /var/log/wtmp. The following example includes output from 'last -aFi', but '-F' isn't always available: :: -0600 root pts/2 Wed Feb 19 14:45:52 2014 still logged in 172.2.81.60 root pts/2 Wed Feb 19 14:45:51 2014 - 14:45:51 (00:00) 172.2.81.60 . . . root pts/1 Tue Feb 18 11:22:51 2014 - 13:40:11 (1+02:17) 172.2.81.60 . . . wtmp begins Mon Feb 17 10:43:39 2014