def __init__(self, output): self._netstats = {} self._local_ports = () self._to_xml = make_to_xml(()) try: del output[:2] except ValueError: raise ValueError("Unexpected output value") for record in (l.strip().split() for l in output): try: proto = record[0] program = record[-1] state = '' laddr, lport = record[3].rsplit(':', 1) faddr, fport = record[4].rsplit(':', 1) # udp/udp6 may have state 'ESTABLISHED'. If so, store it if len(record) == 7: state = record[5] except (IndexError, ValueError): logger.warn('Unable to parse netstat {}'.format(record)) continue netstat = Netstat(proto, laddr, lport, faddr, fport, state, program) if netstat.local_port not in self._netstats: self._netstats[netstat.local_port] = [] self._netstats[netstat.local_port].append(netstat) self._sorted_ports = tuple(sorted(self._netstats.keys(), key=int))
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')
def __init__(self, output): self._logins = {} self._to_xml = make_to_xml(()) try: tz = output.pop(0).strip() except IndexError: raise ValueError('Unable to initialize FailedLogins object: ' + 'no output received') if not output: raise ValueError('Unable to initialize FailedLogins object: ' + 'got timezone but no further output') # Start big, nasty kludge to deal with missing year in output last_date = datetime.now() year = last_date.year for line in output: try: # Parse output into sensible chunks month, day, time, _, process, vestige = line.split(None, 5) vestige, source, _, port, _ = vestige.rsplit(None, 4) vestige, reason, user, _ = vestige.rsplit(None, 3) except ValueError: logger.warn('Unable to parse failed login {}'.format(line)) continue # Create datetime object from the local time date = datetime.strptime(' '.join((month, day, time, str(year))), "%b %d %H:%M:%S %Y") # If time appears to reverse, decrement the year by one if date > last_date: year -= 1 date.replace(year=year) # Set last_date to this one and convert to UTC in ISO 8601 format last_date = date utc = adjust_time(date, tz) timestamp = utc.replace(tzinfo=pytz.UTC).isoformat() # Remove colon from end of process process = process.rstrip(':') # Interpret reason for failure reason = 'username' if reason == 'user' else 'password' # Create a new Login object login = Login(source, port, user, timestamp, process, reason) # Store the login in our internal dict try: self._logins[source].append(login) except KeyError: self._logins[source] = [login]
def __init__(self, output): self._mounts = [] self._to_xml = make_to_xml(()) try: for record in (l.strip().split() for l in output): fs_mntops = record[5].strip('()') self._mounts.append(Mount(*(record[:5:2] + [fs_mntops]))) except (IndexError, ValueError): # If not enough fields in record, raise ValueError('Unable to initialize Mounts object')
def __init__(self, output): self._sudologs = {} self._to_xml = make_to_xml(()) try: tz = output.pop(0).strip() except IndexError: raise ValueError('Unable to initialize SudoLogs object: ' + 'no output received') if not output: raise ValueError('Unable to initialize SudoLogs object: ' + 'got timezone but no further output') # Start big, nasty kludge to deal with missing year in output last_date = datetime.now() year = last_date.year for line in output: try: # Parse output into sensible chunks month, day, time, _, _, user, vestige = line.split(None, 6) _, vestige = vestige.split('=', 1) tty, _, pwd, _, pseudo, vestige = vestige.split(None, 5) _, command = vestige.split(None, 1) except ValueError: logger.warn("Unable to parse sudo log '{}'".format(line)) continue # Create datetime object from the local time date = datetime.strptime(' '.join((month, day, time, str(year))), "%b %d %H:%M:%S %Y") # If time appears to reverse, decrement the year by one if date > last_date: year -= 1 date.replace(year=year) # Set last_date to this one and convert to UTC in ISO 8601 format last_date = date utc = adjust_time(date, tz) timestamp = utc.replace(tzinfo=pytz.UTC).isoformat() # Remove "XXXX=" from log elements args = [i.split('=', 1)[1] for i in (pwd, pseudo, command)] # Create a new Log object sudolog = Log(user, timestamp, tty, *args) # Store the log in our internal dict try: self._sudologs[user].append(sudolog) except KeyError: self._sudologs[user] = [sudolog]
def __init__(self, output): self._arch = None self._name = None self._os = None self._release = None self._version = None self._to_xml = make_to_xml(('name', 'release', 'version', 'architecture')) try: self._name, self._release, vestige = output[0].split(None, 2) vestige, self._arch, self._os = vestige.rsplit(None, 2) self._version = vestige except (IndexError, TypeError, ValueError): raise ValueError('Unable to initialize Kernel object')
def __init__(self, output): self._processes = {} self._sorted_pids = [] self._to_xml = make_to_xml(()) try: tz = output.pop(0).strip() # Capture UTC offset del output[0] # Remove column headers except IndexError: raise ValueError("Unable to initialize Processes object") for record in (l.strip().split() for l in output): try: local = datetime.strptime(' '.join(record[5:10]), "%a %b %d %H:%M:%S %Y") utc = adjust_time(local, tz) # Make datetime object timezone-aware started = utc.replace(tzinfo=pytz.UTC).isoformat() if '-' in record[10]: days, hms = record[10].split('-') else: days, hms = 0, record[10] hours, minutes, seconds = hms.split(':', 2) months, days = divmod(int(days), 30) years, months = divmod(months, 12) cpu_time = 'P{}Y{}M{}DT{}H{}M{}S'.format(str(years).zfill(4), str(months).zfill(2), str(days).zfill(2), hours.zfill(2), minutes.zfill(2), seconds.zfill(2)) process = Process(*(record[0:5] + [started, cpu_time, record[11]] + [' '.join(record[12:])])) self._processes[process.pid] = process except (IndexError, ValueError): # If not enough fields in record, logger.warn('Unable to parse process {}'.format(record)) self._sorted_pids = sorted(self._processes.keys(), key=int)
def __init__(self, output): self._packages = [] self._to_xml = make_to_xml(()) for record in (l.strip().split() for l in output): try: self._packages.append(Package(*record)) except TypeError: self._packages.append(Package(record, '')) except ValueError: # If not enough fields in record, try: self._packages.append(Package(record[0], '')) except IndexError: logger.warn('Unable to parse package {}'. format(str(record)))
def __init__(self, output, shadow=True): self._users = {} self._to_xml = make_to_xml(()) for record in (l.strip().split(":") for l in output): try: username = record[0] epoch = datetime(1970, 1, 1) time_since_change = timedelta(days=int(record[2])) # If we're reading from /etc/passwd, make last_change the epoch if not shadow: time_since_change = 0 last_change = (epoch + time_since_change).isoformat() self._users[username] = User(*(record[:2] + [last_change])) except (IndexError, ValueError): # If not enough fields in record, logger.warn("Unable to parse user {}".format(record))
# as published by Sam Hocevar. See the COPYING.WTFPL file for more details. __author__ = 'jdmorts' from collections import namedtuple 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__) group_attrs = ('group_name', 'password', 'gid', 'users') Group = namedtuple('Group', group_attrs) Group.to_xml = make_to_xml(group_attrs[:3]) User = make_container('User', ('username',)) class Groups(object): """""" def __init__(self, output): self._groups = {} for record in (l.strip().split(':') for l in output): try: group = Group(*(record[:3] + [[User(u) for u in record[3].split(',') if u]]))
def __init__(self, address): super(Linux, self).__init__('Linux', address) self._to_xml = make_to_xml(('type', 'address', '_current_time'))
def __init__(self, platform_type, address): super(IterablePlatform, self).__init__(platform_type, address) self._to_xml = make_to_xml(())
def __init__(self, output, last_only=False): self._logins = {} self._to_xml = make_to_xml(()) try: tz = output.pop(0).strip() except IndexError: raise ValueError('Unable to initialize LastLogins object') # Start big, nasty kludge to deal with missing year in output last_date = datetime.now() year = last_date.year for line in output: try: # Parse output into sensible chunks username, tty, day_of_week, vestige = line.split(None, 3) # month, day, time, year, vestige = vestige.split(None, 4) month, day, time, vestige = vestige.split(None, 3) vestige, duration, source = vestige.rsplit(None, 2) except ValueError: logger.warn('Unable to parse last_login {}'.format(line)) continue # Create datetime object from the local time date = datetime.strptime(' '.join((day_of_week, month, day, time, str(year))), "%a %b %d %H:%M %Y") # If time appears to reverse, decrement the year by one if date > last_date: year -= 1 date.replace(year=year) # Set last_date to this one and convert to UTC in ISO 8601 format last_date = date utc = adjust_time(date, tz) timestamp = utc.replace(tzinfo=pytz.UTC).isoformat() if duration == 'in': duration = 'still logged in' else: duration = duration.strip('()') # Detect days in duration output if '+' in duration: days, hm = duration.split('+', 1) else: days, hm = 0, duration # Calculate months, years from days for ISO 8601 format hours, minutes = hm.split(':', 1) months, days = divmod(int(days), 30) years, months = divmod(months, 12) duration = 'P{}Y{}M{}DT{}H{}M00S'.format(str(years).zfill(4), str(months).zfill(2), str(days).zfill(2), hours.zfill(2), minutes.zfill(2)) # If last_only==True, capture only the first (most recent) login if last_only is True and username in self._logins: continue # Create a new Login object login = Login(username, tty, timestamp, duration, source) # Store the login in our internal dict try: self._logins[username].append(login) except KeyError: self._logins[username] = [login]