#! /usr/bin/python -Es
# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
# Authors: Dan Walsh <dwalsh@redhat.com>
#
# 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
import 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
try:
    locale.setlocale(locale.LC_ALL, '')
except:
    pass


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("-x", "--xperms", action="store_true", dest="xperms",
                          default=False, help="generate extended permission rules")
        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 as 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 as 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 as 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 as 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 as 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 sepolicy
        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")
                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")
                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" % sepolicy.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" % sepolicy.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:")
                print("\n#\t" + data[0])
                for reason in data[1:]:
                    print("#\tPossible cause is the source %s and target %s are different.\n" % reason)

            if rc == audit2why.RBAC:
                print("\t\tMissing role allow rule.\n")
                print("\t\tAdd an allow rule for the role pair.\n")
                continue

            if rc == audit2why.BOUNDS:
                print("\t\tTypebounds violation.\n")
                print("\t\tAdd an allow rule for the parent type.\n")
                continue

        audit2why.finish()
        return

    def __output(self):

        if self.__options.audit2why:
            try:
                return self.__output_audit2why()
            except RuntimeError as 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)

        # Extended permissions
        if self.__options.xperms:
            g.set_gen_xperms(True)

        # 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 as e:
            print(e)
            sys.exit(1)
        except IOError as e:
            print(e)
            sys.exit(1)

if __name__ == "__main__":
    app = AuditToPolicy()
    app.main()
