[PATCH 30/74] Handle audit2allow and audit2why with the same

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This patch makes audit2allow and audit2why the same executable rather then
shipping a script for audit2why.

   This patch looks good to me. acked.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.15 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlJpK6AACgkQrlYvE4MpobP0PgCgu0DHfFJAlFHAsaX2jwm3bp4s
Fu4Anirsw1VbNIVplyA1e15U/QZRq/dh
=f6/M
-----END PGP SIGNATURE-----
>From 7005650148e4100d813e675d84ca7b1c451f8696 Mon Sep 17 00:00:00 2001
From: Dan Walsh <dwalsh@xxxxxxxxxx>
Date: Wed, 9 Oct 2013 17:19:30 -0400
Subject: [PATCH 30/74] Handle audit2allow and audit2why with the same
 executable Remove audit2why directory and combine this into audit2allow
 directory

---
 policycoreutils/Makefile                |   2 +-
 policycoreutils/audit2allow/Makefile    |   7 +-
 policycoreutils/audit2allow/audit2allow |   8 +-
 policycoreutils/audit2allow/audit2why   | 359 ++++++++++++++++++++++++++++++++
 policycoreutils/audit2allow/audit2why.1 |   1 +
 policycoreutils/audit2why/Makefile      |  18 --
 policycoreutils/audit2why/audit2why     |   2 -
 policycoreutils/audit2why/audit2why.1   |   1 -
 8 files changed, 371 insertions(+), 27 deletions(-)
 create mode 100644 policycoreutils/audit2allow/audit2why
 create mode 100644 policycoreutils/audit2allow/audit2why.1
 delete mode 100644 policycoreutils/audit2why/Makefile
 delete mode 100644 policycoreutils/audit2why/audit2why
 delete mode 100644 policycoreutils/audit2why/audit2why.1

diff --git a/policycoreutils/Makefile b/policycoreutils/Makefile
index 3980799..83ebd45 100644
--- a/policycoreutils/Makefile
+++ b/policycoreutils/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS = sepolicy setfiles semanage load_policy newrole run_init sandbox secon audit2allow audit2why sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui
+SUBDIRS = sepolicy setfiles semanage load_policy newrole run_init sandbox secon audit2allow sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool scripts po man gui
 
 INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null)
 
diff --git a/policycoreutils/audit2allow/Makefile b/policycoreutils/audit2allow/Makefile
index 88635d4..fc290ea 100644
--- a/policycoreutils/audit2allow/Makefile
+++ b/policycoreutils/audit2allow/Makefile
@@ -5,14 +5,19 @@ LIBDIR ?= $(PREFIX)/lib
 MANDIR ?= $(PREFIX)/share/man
 LOCALEDIR ?= /usr/share/locale
 
-all: ;
+all: audit2why
+
+audit2why:
+	ln -sf audit2allow audit2why
 
 install: all
 	-mkdir -p $(BINDIR)
 	install -m 755 audit2allow $(BINDIR)
+	(cd $(BINDIR); ln -sf audit2allow audit2why)
 	install -m 755 sepolgen-ifgen $(BINDIR)
 	-mkdir -p $(MANDIR)/man1
 	install -m 644 audit2allow.1 $(MANDIR)/man1/
+	install -m 644 audit2why.1 $(MANDIR)/man1/
 
 clean:
 	rm -f *~
diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow
index 49a342d..9f5185d 100644
--- a/policycoreutils/audit2allow/audit2allow
+++ b/policycoreutils/audit2allow/audit2allow
@@ -1,7 +1,8 @@
 #! /usr/bin/python -Es
 # Authors: Karl MacMillan <kmacmillan@xxxxxxxxxxxxxxxxx>
+# Authors: Dan Walsh <dwalsh@xxxxxxxxxx>
 #
-# Copyright (C) 2006-2007  Red Hat
+# Copyright (C) 2006-2013  Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # This program is free software; you can redistribute it and/or
@@ -18,7 +19,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
-import sys
+import sys, os
 
 import sepolgen.audit as audit
 import sepolgen.policygen as policygen
@@ -82,8 +83,7 @@ class AuditToPolicy:
         parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
         parser.add_option("--debug", dest="debug", action="store_true", default=False,
                           help="leave generated modules for -M")
-
-        parser.add_option("-w", "--why", dest="audit2why",  action="store_true", default=False,
+        parser.add_option("-w", "--why", dest="audit2why",  action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
                           help="Translates SELinux audit messages into a description of why the access was denied")
 
         options, args = parser.parse_args()
diff --git a/policycoreutils/audit2allow/audit2why b/policycoreutils/audit2allow/audit2why
new file mode 100644
index 0000000..9f5185d
--- /dev/null
+++ b/policycoreutils/audit2allow/audit2why
@@ -0,0 +1,359 @@
+#! /usr/bin/python -Es
+# Authors: Karl MacMillan <kmacmillan@xxxxxxxxxxxxxxxxx>
+# Authors: Dan Walsh <dwalsh@xxxxxxxxxx>
+#
+# Copyright (C) 2006-2013  Red Hat
+# 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, os
+
+import sepolgen.audit as audit
+import sepolgen.policygen as policygen
+import sepolgen.interfaces as interfaces
+import sepolgen.output as output
+import sepolgen.objectmodel as objectmodel
+import sepolgen.defaults as defaults
+import sepolgen.module as module
+from sepolgen.sepolgeni18n import _
+import selinux.audit2why as audit2why
+import locale
+locale.setlocale(locale.LC_ALL, '')
+
+class AuditToPolicy:
+    VERSION = "%prog .1"
+    SYSLOG = "/var/log/messages"
+
+    def __init__(self):
+        self.__options = None
+        self.__parser = None
+        self.__avs = None
+
+    def __parse_options(self):
+        from optparse import OptionParser
+
+        parser = OptionParser(version=self.VERSION)
+        parser.add_option("-b", "--boot", action="store_true", dest="boot", default=False,
+                          help="audit messages since last boot conflicts with -i")
+        parser.add_option("-a", "--all", action="store_true", dest="audit", default=False,
+                          help="read input from audit log - conflicts with -i")
+        parser.add_option("-p", "--policy", dest="policy", default=None, help="Policy file to use for analysis")
+        parser.add_option("-d", "--dmesg", action="store_true", dest="dmesg", default=False,
+                          help="read input from dmesg - conflicts with --all and --input")
+        parser.add_option("-i", "--input", dest="input",
+                          help="read input from <input> - conflicts with -a")
+        parser.add_option("-l", "--lastreload", action="store_true", dest="lastreload", default=False,
+                          help="read input only after the last reload")
+        parser.add_option("-r", "--requires", action="store_true", dest="requires", default=False,
+                          help="generate require statements for rules")
+        parser.add_option("-m", "--module", dest="module",
+                          help="set the module name - implies --requires")
+        parser.add_option("-M", "--module-package", dest="module_package",
+                          help="generate a module package - conflicts with -o and -m")
+        parser.add_option("-o", "--output", dest="output",
+                          help="append output to <filename>, conflicts with -M")
+        parser.add_option("-D", "--dontaudit", action="store_true", 
+                          dest="dontaudit", default=False, 
+                          help="generate policy with dontaudit rules")
+        parser.add_option("-R", "--reference", action="store_true", dest="refpolicy",
+                          default=True, help="generate refpolicy style output")
+
+        parser.add_option("-N", "--noreference", action="store_false", dest="refpolicy",
+                          default=False, help="do not generate refpolicy style output")
+        parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+                          default=False, help="explain generated output")
+        parser.add_option("-e", "--explain", action="store_true", dest="explain_long",
+                          default=False, help="fully explain generated output")
+        parser.add_option("-t", "--type", help="only process messages with a type that matches this regex",
+                          dest="type")
+        parser.add_option("--perm-map", dest="perm_map", help="file name of perm map")
+        parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
+        parser.add_option("--debug", dest="debug", action="store_true", default=False,
+                          help="leave generated modules for -M")
+        parser.add_option("-w", "--why", dest="audit2why",  action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
+                          help="Translates SELinux audit messages into a description of why the access was denied")
+
+        options, args = parser.parse_args()
+
+        # Make -d, -a, and -i conflict
+        if options.audit is True or options.boot:
+            if options.input is not None:
+                sys.stderr.write("error: --all/--boot conflicts with --input\n")
+            if options.dmesg is True:
+                sys.stderr.write("error: --all/--boot conflicts with --dmesg\n")
+        if options.input is not None and options.dmesg is True:
+            sys.stderr.write("error: --input conflicts with --dmesg\n")
+
+        # Turn on requires generation if a module name is given. Also verify
+        # the module name.
+        if options.module:
+            name = options.module
+        else:
+            name = options.module_package
+        if name:
+            options.requires = True
+            if not module.is_valid_name(name):
+                sys.stderr.write('error: module names must begin with a letter, optionally followed by letters, numbers, "-", "_", "."\n')
+                sys.exit(2)
+
+        # Make -M and -o conflict
+        if options.module_package:
+            if options.output:
+                sys.stderr.write("error: --module-package conflicts with --output\n")
+                sys.exit(2)
+            if options.module:
+                sys.stderr.write("error: --module-package conflicts with --module\n")
+                sys.exit(2)
+
+        self.__options = options
+
+    def __read_input(self):
+        parser = audit.AuditParser(last_load_only=self.__options.lastreload)
+
+        filename = None
+        messages = None
+        f = None
+
+        # Figure out what input we want
+        if self.__options.input is not None:
+            filename = self.__options.input
+        elif self.__options.dmesg:
+            messages = audit.get_dmesg_msgs()
+        elif self.__options.audit:
+            try:
+                messages = audit.get_audit_msgs()
+            except OSError, e:
+                sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
+                sys.exit(1)
+        elif self.__options.boot:
+            try:
+                messages = audit.get_audit_boot_msgs()
+            except OSError, e:
+                sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
+                sys.exit(1)
+        else:
+            # This is the default if no input is specified
+            f = sys.stdin
+
+        # Get the input
+        if filename is not None:
+            try:
+                f = open(filename)
+            except IOError, e:
+                sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e)))
+                sys.exit(1)
+
+        if f is not None:
+            parser.parse_file(f)
+            f.close()
+
+        if messages is not None:
+            parser.parse_string(messages)
+
+        self.__parser = parser
+
+    def __process_input(self):
+        if self.__options.type:
+            avcfilter = audit.AVCTypeFilter(self.__options.type)
+            self.__avs = self.__parser.to_access(avcfilter)
+            csfilter = audit.ComputeSidTypeFilter(self.__options.type)
+            self.__role_types = self.__parser.to_role(csfilter)
+        else:
+            self.__avs = self.__parser.to_access()
+            self.__role_types = self.__parser.to_role()
+
+    def __load_interface_info(self):
+        # Load interface info file
+        if self.__options.interface_info:
+            fn = self.__options.interface_info
+        else:
+            fn = defaults.interface_info()
+        try:
+            fd = open(fn)
+        except:
+            sys.stderr.write("could not open interface info [%s]\n" % fn)
+            sys.exit(1)
+
+        ifs = interfaces.InterfaceSet()
+        ifs.from_file(fd)
+        fd.close()
+
+        # Also load perm maps
+        if self.__options.perm_map:
+            fn = self.__options.perm_map
+        else:
+            fn = defaults.perm_map()
+        try:
+            fd = open(fn)
+        except:
+            sys.stderr.write("could not open perm map [%s]\n" % fn)
+            sys.exit(1)
+
+        perm_maps = objectmodel.PermMappings()
+        perm_maps.from_file(fd)
+
+        return (ifs, perm_maps)
+
+    def __output_modulepackage(self, writer, generator):
+        generator.set_module_name(self.__options.module_package)
+        filename = self.__options.module_package + ".te"
+        packagename = self.__options.module_package + ".pp"
+
+        try:
+            fd = open(filename, "w")
+        except IOError, e:
+            sys.stderr.write("could not write output file: %s\n" % str(e))
+            sys.exit(1)
+
+        writer.write(generator.get_module(), fd)
+        fd.close()
+
+        mc = module.ModuleCompiler()
+
+        try:
+            mc.create_module_package(filename, self.__options.refpolicy)
+        except RuntimeError, e:
+            print e
+            sys.exit(1)
+
+        sys.stdout.write(_("******************** IMPORTANT ***********************\n"))
+        sys.stdout.write((_("To make this policy package active, execute:" +\
+                                "\n\nsemodule -i %s\n\n") % packagename))
+
+    def __output_audit2why(self):
+            import selinux
+            import seobject
+            for i in self.__parser.avc_msgs:
+                rc = i.type
+                data = i.data
+                if rc >= 0:
+                    print "%s\n\tWas caused by:" % i.message
+                if rc == audit2why.ALLOW:
+                    print "\t\tUnknown - would be allowed by active policy\n",
+                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
+                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
+                    continue
+                if rc == audit2why.DONTAUDIT:
+                    print "\t\tUnknown - should be dontaudit'd by active policy\n",
+                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
+                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
+                    continue
+                if rc == audit2why.BOOLEAN:
+                    if len(data) > 1:
+                        print "\tOne of the following booleans was set incorrectly."
+                        for b in data:
+                            print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(b[0])
+                            print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (b[0], b[1])
+                    else:
+                        print "\tThe boolean %s was set incorrectly. " % (data[0][0])
+                        print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(data[0][0])
+                        print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (data[0][0], data[0][1])
+                    continue
+
+                if rc == audit2why.TERULE:
+                    print "\t\tMissing type enforcement (TE) allow rule.\n"
+                    print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n"
+                    continue
+
+                if rc == audit2why.CONSTRAINT:
+                    print #!!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.\n"
+                    print "#Constraint rule: \n\t" + data[0]
+                    for reason in data[1:]:
+                        print "#\tPossible cause is the source %s and target %s are different.\n\b" % reason
+
+                if rc == audit2why.RBAC:
+                    print "\t\tMissing role allow rule.\n"
+                    print "\t\tAdd an allow rule for the role pair.\n"
+                    continue
+
+            audit2why.finish()
+            return
+
+    def __output(self):
+        
+        if self.__options.audit2why:
+            try:
+                return self.__output_audit2why()
+            except RuntimeError, e:
+                print e
+                sys.exit(1)
+
+        g = policygen.PolicyGenerator()
+
+        g.set_gen_dontaudit(self.__options.dontaudit)
+
+        if self.__options.module:
+            g.set_module_name(self.__options.module)
+
+        # Interface generation
+        if self.__options.refpolicy:
+            ifs, perm_maps = self.__load_interface_info()
+            g.set_gen_refpol(ifs, perm_maps)
+
+        # Explanation
+        if self.__options.verbose:
+            g.set_gen_explain(policygen.SHORT_EXPLANATION)
+        if self.__options.explain_long:
+            g.set_gen_explain(policygen.LONG_EXPLANATION)
+
+        # Requires
+        if self.__options.requires:
+            g.set_gen_requires(True)
+
+        # Generate the policy
+        g.add_access(self.__avs)
+        g.add_role_types(self.__role_types)
+
+        # Output
+        writer = output.ModuleWriter()
+
+        # Module package
+        if self.__options.module_package:
+            self.__output_modulepackage(writer, g)
+        else:
+            # File or stdout
+            if self.__options.module:
+                g.set_module_name(self.__options.module)
+
+            if self.__options.output:
+                fd = open(self.__options.output, "a")
+            else:
+                fd = sys.stdout
+            writer.write(g.get_module(), fd)
+
+    def main(self):
+        try:
+            self.__parse_options()
+            if self.__options.policy:
+                audit2why.init(self.__options.policy)
+            else:
+                audit2why.init()
+
+            self.__read_input()
+            self.__process_input()
+            self.__output()
+        except KeyboardInterrupt:
+            sys.exit(0)
+        except ValueError, e:
+            print e
+            sys.exit(1)
+        except IOError, e:
+            print e
+            sys.exit(1)
+
+if __name__ == "__main__":
+    app = AuditToPolicy()
+    app.main()
diff --git a/policycoreutils/audit2allow/audit2why.1 b/policycoreutils/audit2allow/audit2why.1
new file mode 100644
index 0000000..a9e8893
--- /dev/null
+++ b/policycoreutils/audit2allow/audit2why.1
@@ -0,0 +1 @@
+.so man1/audit2allow.1
diff --git a/policycoreutils/audit2why/Makefile b/policycoreutils/audit2why/Makefile
deleted file mode 100644
index 63eb8b3..0000000
--- a/policycoreutils/audit2why/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# Installation directories.
-PREFIX ?= $(DESTDIR)/usr
-BINDIR ?= $(PREFIX)/bin
-MANDIR ?= $(PREFIX)/share/man
-
-TARGETS=audit2why
-
-all: $(TARGETS)
-
-install: all
-	-mkdir -p $(BINDIR)
-	install -m 755 $(TARGETS) $(BINDIR)
-	-mkdir -p $(MANDIR)/man1
-	install -m 644 audit2why.1 $(MANDIR)/man1/
-
-clean:
-
-relabel:
diff --git a/policycoreutils/audit2why/audit2why b/policycoreutils/audit2why/audit2why
deleted file mode 100644
index 21a72aa..0000000
--- a/policycoreutils/audit2why/audit2why
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-/usr/bin/audit2allow -w $*
diff --git a/policycoreutils/audit2why/audit2why.1 b/policycoreutils/audit2why/audit2why.1
deleted file mode 100644
index a9e8893..0000000
--- a/policycoreutils/audit2why/audit2why.1
+++ /dev/null
@@ -1 +0,0 @@
-.so man1/audit2allow.1
-- 
1.8.3.1


[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux