diff -urN a/audit-1.5.6/bindings/python/auditparser.py.in b/audit-1.5.6/bindings/python/auditparser.py.in --- a/audit-1.5.6/bindings/python/auditparser.py.in 1969-12-31 19:00:00.000000000 -0500 +++ b/audit-1.5.6/bindings/python/auditparser.py.in 2007-08-09 15:29:25.000000000 -0400 @@ -0,0 +1,270 @@ +#! /usr/bin/python -E + +"""A high-level parser for audit logs. + +Provides AuditLog, which produces an iteration of audit events as a +sequence of dictionary objects. + +To produces a quick one-off audit processing script, copy this source +file and then edit the run function to suit your needs. + +Package: @PACKAGE@ +Version: @VERSION@ + +""" + +# Authors: John D. Ramsdell +# +# Copyright (C) 2007 The MITRE Corporation +# see file 'COPYING' for use and warranty information +# +# 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 only +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import sys, getopt, auparse, os.path, copy, string + +# Log Parsing + +class AuditLog(object): + """AuditLog(AuParser or file, bool) + + Encapsulates a log accessed by the auparse module. It provides an + iterator to the log's events. Each call to the next method of + the iterator returns an AuditEvent. The boolean determines if + numeric entities in fields are interpreted. + + """ + def __init__(self, au, interpret = False): + if isinstance(au, file): + self.au = auparse.AuParser(auparse.AUSOURCE_FILE_POINTER, au) + else: + self.au = au + self.interpret = interpret + + def __iter__(self): + return AuditLogIter(self) + +class AuditLogIter(object): + """AuditLogIter(AuditLog) + + An iterator for an audit log. + + """ + def __init__(self, aulog): + self.au = aulog.au + self.filename = self.au.get_filename() + self.interpret = aulog.interpret + + def next(self): + """Returns an AuditEvent + + """ + au = self.au + interpret = self.interpret + if not au.parse_next_event(): + raise StopIteration() + event = AuditEvent(au.get_timestamp(), self.filename) + for i in range(au.get_num_records()): + record = AuditRecord(event, au.get_line_number()) + for j in range(au.get_num_fields()): + name = au.get_field_name() + if interpret: + value = au.interpret_field() + else: + value = au.get_field_str() + record[name] = value + au.next_field() + event.append(record) + au.next_record() + return event + +class AuditEvent(list): + """AuditEvent(AuEvent, string) + + An audit event is represented as a list of AuditRecord's. Each + AuditRecord is a dictionary that represents one of the records + that make up the event. The string is a filename giving the + source of the event. + + """ + def __init__(self, timestamp, filename = None): + self.timestamp = timestamp + self.filename = filename + + def get_timestamp(self): + """Get the timestamp associated with this event.""" + return self.timestamp + + def get_filename(self): + """Get the filename associated with this event.""" + return self.filename + + def find_record_of_type(self, type): + """Find record of type + + Returns a record in the event that has the given type. + Returns None when there is no such record. + + """ + for record in self: + try: + if record["type"] == type: + return record + except KeyError: + pass + return None + + def find_value(self, name): + """Find a value + + Returns a value associated with the given name in some record + in the event. Raises KeyError if no field has the given name. + + """ + for record in self: + try: + return record[name] + except KeyError: + pass + raise KeyError + + def find_path_record(self, item): + """Find a PATH record for the given item. + + Returns the PATH record for the given item. Return None if + PATH record cannot be found. + + """ + item = str(item) # Ensure item is a string + for record in self: + if record.is_path_record(item): + return record + return None + +class AuditRecord(dict): + """AuditRecord(AuditEvent, int) + + An audit record is a dictionary. The int is the line number + associated with the source of the record. + + """ + def __init__(self, event, line_number): + self.event = event + self.line_number = line_number + + def get_event(self): + """Get the event associated with this record.""" + return self.event + + def get_line_number(self): + """Get the line number associated with this record.""" + return self.line_number + + def get_source(self): + """Get the source of this record as a string.""" + serial = self.get_event().get_timestamp().serial + source = "%d (serial=%d)" % (self.line_number, serial) + filename = self.get_event().get_filename() + if filename: + return filename + ":" + source + else: + return source + + def is_path_record(self, item): + """Is this a PATH record for the given item?""" + try: + return self["type"] == "PATH" and self["item"] == item + except KeyError: + return False + +def args2aulog(): + """Make an AuditLog from command line arguments + + Create an audit log object based on the command line arguments + passsed to this program. + + Returns an AuditLog. + + """ + interpret = False # Event reading mode + output_file = None # Output file name for results + try: + long_opts = ["help", "interpret", "raw", "output="] + opts, args = getopt.getopt(sys.argv[1:], "hiro:", long_opts) + except getopt.GetoptError: + # Bad options + usage() + sys.exit(2) + for o, a in opts: + if o in ("-h", "--help"): + # Print help information + usage() + sys.exit(0) + elif o in ("-i", "--interpret"): + interpret = True + elif o in ("-r", "--raw"): + interpret = False + elif o in ("-o", "--output"): + # Record output file name + output_file = a + # Determine input source + if len(args) > 0: + au = auparse.AuParser(auparse.AUSOURCE_FILE_ARRAY, args) + sys.stdin.close() + else: + au = sys.stdin + # Open output file as standard output + if output_file: + sys.stdout.close() + try: + sys.stdout = file(output_file, 'w') + except IOError: + sys.stderr.write("cannot open %s for writing" % output_file) + sys.exit(1) + return AuditLog(au, interpret) + +def usage(): + """Show usage + + Print a ussage message that includes version information. + + """ + help = """Version: %s %s +Usage: %s [OPTIONS] [FILE...] + + -o FILE, --output=FILE output to FILE (default is standard output) + -i, --interpret interpret numeric entities into text + -r --raw do not interpret numeric entities (default) + -h, --help print this message and exit + +With no FILEs, read from the standard input. +""" + sys.stderr.write(help % ("@PACKAGE@", "@VERSION@", sys.argv[0])) + +# Consume a log + +def run(log): + """The main loop for consuming a log. Modify this to suit your needs.""" + for event in log: + print event + +def main(): + """Main routine + + Perform command line processing and then conume the log. + + """ + run(args2aulog()) + +if __name__ == "__main__": + main() diff -urN a/audit-1.5.6/bindings/python/Makefile.am b/audit-1.5.6/bindings/python/Makefile.am --- a/audit-1.5.6/bindings/python/Makefile.am 2007-07-25 14:17:26.000000000 -0400 +++ b/audit-1.5.6/bindings/python/Makefile.am 2007-07-27 11:39:56.000000000 -0400 @@ -21,7 +21,7 @@ # CONFIG_CLEAN_FILES = Makefile.in *.loT *.rej *.orig -EXTRA_DIST = setup.py auparse_python.c +EXTRA_DIST = setup.py auparse_python.c auditparser.py all: $(PYTHON) setup.py build diff -urN a/audit-1.5.6/bindings/python/setup.py b/audit-1.5.6/bindings/python/setup.py --- a/audit-1.5.6/bindings/python/setup.py 2007-05-01 18:06:23.000000000 -0400 +++ b/audit-1.5.6/bindings/python/setup.py 2007-07-27 11:54:34.000000000 -0400 @@ -11,3 +11,8 @@ description = 'python binding for audit parsing (auparse)', ext_modules = [auparse]) +setup(name = 'auditparser', + version = '1.0', + description = 'high-level python binding for audit parsing', + py_modules = ['auditparser']) + diff -urN a/audit-1.5.6/configure.ac b/audit-1.5.6/configure.ac --- a/audit-1.5.6/configure.ac 2007-07-23 14:39:31.000000000 -0400 +++ b/audit-1.5.6/configure.ac 2007-07-27 11:41:06.000000000 -0400 @@ -109,7 +109,7 @@ AC_DEFINE(WITH_APPARMOR,1,[Define if you want to enable AppArmor events.])fi AC_CONFIG_SUBDIRS([system-config-audit]) -AC_OUTPUT(Makefile lib/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile bindings/Makefile bindings/python/Makefile) +AC_OUTPUT(Makefile lib/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile bindings/Makefile bindings/python/Makefile bindings/python/auditparser.py) echo . echo "