#! /usr/bin/python -Es
# Copyright (C) 2012 Red Hat
# AUTHOR: Dan Walsh <dwalsh@redhat.com>
# see file 'COPYING' for use and warranty information
#
# semanage is a tool for managing SELinux configuration files
#
#    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; either version 2 of
#    the License, or (at your option) any later version.
#
#    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 os
import sys
import selinux
import sepolicy
from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text
import argparse
import gettext
PROGNAME = "policycoreutils"
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
    gettext.install(PROGNAME,
                    localedir="/usr/share/locale",
                    unicode=False,
                    codeset='utf-8')
except IOError:
    import __builtin__
    __builtin__.__dict__['_'] = unicode

usage = "sepolicy generate [-h] [-n NAME] [-p PATH] ["
usage_dict = {' --newtype': ('-t [TYPES [TYPES ...]]',), ' --customize': ('-d DOMAIN', '-a  ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --admin_user': ('[-r TRANSITION_ROLE ]', "[ -w WRITEPATHS ]",), ' --application': ('COMMAND', "[ -w WRITEPATHS ]",), ' --cgi': ('COMMAND', "[ -w WRITEPATHS ]",), ' --confined_admin': ('-a  ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --dbus': ('COMMAND', "[ -w WRITEPATHS ]",), ' --desktop_user': ('', "[ -w WRITEPATHS ]",), ' --inetd': ('COMMAND', "[ -w WRITEPATHS ]",), ' --init': ('COMMAND', "[ -w WRITEPATHS ]",), ' --sandbox': ("[ -w WRITEPATHS ]",), ' --term_user': ("[ -w WRITEPATHS ]",), ' --x_user': ("[ -w WRITEPATHS ]",)}


class CheckPath(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        if not os.path.exists(values):
            raise ValueError("%s does not exist" % values)
        setattr(namespace, self.dest, values)


class CheckType(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        domains = sepolicy.get_all_domains()

        if isinstance(values, str):
            setattr(namespace, self.dest, values)
        else:
            newval = getattr(namespace, self.dest)
            if not newval:
                newval = []

            for v in values:
                newval.append(v)
            setattr(namespace, self.dest, newval)


class CheckBoolean(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        booleans = sepolicy.get_all_booleans()
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []

        if isinstance(values, str):
            v = selinux.selinux_boolean_sub(values)
            if v not in booleans:
                raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans)))
            newval.append(v)
            setattr(namespace, self.dest, newval)
        else:
            for value in values:
                v = selinux.selinux_boolean_sub(value)
                if v not in booleans:
                    raise ValueError("%s must be an SELinux boolean:\nValid boolean: %s" % (v, ", ".join(booleans)))
                newval.append(v)
            setattr(namespace, self.dest, newval)


class CheckDomain(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        domains = sepolicy.get_all_domains()

        if isinstance(values, str):
            if values not in domains:
                raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains)))
            setattr(namespace, self.dest, values)
        else:
            newval = getattr(namespace, self.dest)
            if not newval:
                newval = []

            for v in values:
                if v not in domains:
                    raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(domains)))
                newval.append(v)
            setattr(namespace, self.dest, newval)

all_classes = None


class CheckClass(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        global all_classes
        if not all_classes:
            all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
        if values not in all_classes:
            raise ValueError("%s must be an SELinux class:\nValid classes: %s" % (values, ", ".join(all_classes)))

        setattr(namespace, self.dest, values)


class CheckAdmin(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        from sepolicy.interface import get_admin
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        admins = get_admin()
        if values not in admins:
            raise ValueError("%s must be an SELinux admin domain:\nValid admin domains: %s" % (values, ", ".join(admins)))
        newval.append(values)
        setattr(namespace, self.dest, newval)


class CheckPort(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        for v in values:
            if v < 1 or v > 65536:
                raise ValueError("%s must be an integer between 1 and 65536" % v)
            newval.append(v)
        setattr(namespace, self.dest, newval)


class CheckPortType(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        port_types = sepolicy.get_all_port_types()
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        for v in values:
            if v not in port_types:
                raise ValueError("%s must be an SELinux port type:\nValid port types: %s" % (v, ", ".join(port_types)))
            newval.append(v)
        setattr(namespace, self.dest, values)


class LoadPolicy(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        import sepolicy
        sepolicy.policy(values)
        setattr(namespace, self.dest, values)


class CheckPolicyType(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        from sepolicy.generate import get_poltype_desc, poltype
        if values not in poltype.keys():
            raise ValueError("%s invalid SELinux policy type\n%s" % (values, get_poltype_desc()))
            newval.append(v)
        setattr(namespace, self.dest, values)


class CheckUser(argparse.Action):

    def __call__(self, parser, namespace, value, option_string=None):
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        users = sepolicy.get_all_users()
        if value not in users:
            raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
        newval.append(value)
        setattr(namespace, self.dest, newval)


class CheckRole(argparse.Action):

    def __call__(self, parser, namespace, value, option_string=None):
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        roles = sepolicy.get_all_roles()
        if value not in roles:
            raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
        newval.append(value[:-2])
        setattr(namespace, self.dest, newval)


class InterfaceInfo(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        from sepolicy.interface import get_interface_dict
        interface_dict = get_interface_dict()
        for v in values:
            if v not in interface_dict.keys():
                raise ValueError(_("Interface %s does not exist.") % v)

        setattr(namespace, self.dest, values)


def generate_custom_usage(usage_text, usage_dict):
    sorted_keys = []
    for i in usage_dict.keys():
        sorted_keys.append(i)
    sorted_keys.sort()
    for k in sorted_keys:
        usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
    usage_text = usage_text[:-1] + "]"
    usage_text = _(usage_text)

    return usage_text


def numcmp(val1, val2):
    try:
        v1 = int(val1.split(",")[0].split("-")[0])
        v2 = int(val2.split(",")[0].split("-")[0])
        if v1 > v2:
            return 1
        if v1 == v2:
            return 0
        if v1 < v2:
            return -1
    except:
        return cmp(val1, val2)


def _print_net(src, protocol, perm):
    import sepolicy.network
    portdict = sepolicy.network.get_network_connect(src, protocol, perm)
    if len(portdict) > 0:
        bold_start = "\033[1m"
        bold_end = "\033[0;0m"
        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
        port_strings = []
        boolean_text = ""
        for p in portdict:
            for t, recs in portdict[p]:
                cond = get_conditionals(src, t, "%s_socket" % protocol, [perm])
                if cond:
                    boolean_text = get_conditionals_format_text(cond)
                    port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text))
                else:
                    port_strings.append("%s (%s)" % (", ".join(recs), t))
        port_strings.sort(numcmp)
        for p in port_strings:
            print "\t" + p


def network(args):
    portrecs, portrecsbynum = sepolicy.gen_port_dict()
    all_ports = []
    if args.list_ports:
        for i in portrecs:
            if i[0] not in all_ports:
                all_ports.append(i[0])
        all_ports.sort()
        print "\n".join(all_ports)

    for port in args.port:
        found = False
        for i in portrecsbynum:
            if i[0] <= port and port <= i[1]:
                if i[0] == i[1]:
                    range = i[0]
                else:
                    range = "%s-%s" % (i[0], i[1])
                found = True
                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
        if not found:
            if port < 500:
                print "Undefined reserved port type"
            else:
                print "Undefined port type"

    for t in args.type:
        if (t, 'tcp') in portrecs.keys():
            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
        if (t, 'udp') in portrecs.keys():
            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))

    for a in args.applications:
        d = sepolicy.get_init_transtype(a)
        if d:
            args.domain.append(d)

    for d in args.domain:
        _print_net(d, "tcp", "name_connect")
        for net in ("tcp", "udp"):
            _print_net(d, net, "name_bind")


def gui_run(args):
    try:
        import sepolicy.gui
        sepolicy.gui.SELinuxGui(args.domain, args.test)
        pass
    except ImportError:
        raise ValueError(_("You need to install policycoreutils-gui package to use the gui option"))


def gen_gui_args(parser):
    gui = parser.add_parser("gui",
                            help=_('Graphical User Interface for SELinux Policy'))
    gui.add_argument("-d", "--domain", default=None,
                     action=CheckDomain,
                     help=_("Domain name(s) of man pages to be created"))
    gui.add_argument("-t", "--test", default=False, action="store_true",
                     help=argparse.SUPPRESS)
    gui.set_defaults(func=gui_run)


def manpage(args):
    from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains

    path = args.path
    if not args.policy and args.root != "/":
        sepolicy.policy(sepolicy.get_installed_policy(args.root))
    if args.source_files and args.root == "/":
        raise ValueError(_("Alternative root needs to be setup"))

    if args.all:
        test_domains = gen_domains()
    else:
        test_domains = args.domain

    for domain in test_domains:
        m = ManPage(domain, path, args.root, args.source_files, args.web)
        print m.get_man_page_path()

    if args.web:
        HTMLManPages(manpage_roles, manpage_domains, path, args.os)


def gen_manpage_args(parser):
    man = parser.add_parser("manpage",
                            help=_('Generate SELinux man pages'))

    man.add_argument("-p", "--path", dest="path", default="/tmp",
                     help=_("path in which the generated SELinux man pages will be stored"))
    man.add_argument("-o", "--os", dest="os", default=get_os_version(),
                     help=_("name of the OS for man pages"))
    man.add_argument("-w", "--web", dest="web", default=False, action="store_true",
                     help=_("Generate HTML man pages structure for selected SELinux man page"))
    man.add_argument("-r", "--root", dest="root", default="/",
                     help=_("Alternate root directory, defaults to /"))
    man.add_argument("--source_files", dest="source_files", default=False, action="store_true",
                     help=_("With this flag, alternative root path needs to include file context files and policy.xml file"))
    group = man.add_mutually_exclusive_group(required=True)
    group.add_argument("-a", "--all", dest="all", default=False,
                       action="store_true",
                       help=_("All domains"))
    group.add_argument("-d", "--domain", nargs="+",
                       action=CheckDomain,
                       help=_("Domain name(s) of man pages to be created"))
    man.set_defaults(func=manpage)


def gen_network_args(parser):
    net = parser.add_parser("network",
                            help=_('Query SELinux policy network information'))

    group = net.add_mutually_exclusive_group(required=True)
    group.add_argument("-l", "--list", dest="list_ports",
                       action="store_true",
                       help=_("list all SELinux port types"))
    group.add_argument("-p", "--port", dest="port", default=[],
                       action=CheckPort, nargs="+", type=int,
                       help=_("show SELinux type related to the port"))
    group.add_argument("-t", "--type", dest="type", default=[],
                       action=CheckPortType, nargs="+",
                       help=_("Show ports defined for this SELinux type"))
    group.add_argument("-d", "--domain", dest="domain", default=[],
                       action=CheckDomain, nargs="+",
                       help=_("show ports to which this domain can bind and/or connect"))
    group.add_argument("-a", "--application", dest="applications", default=[],
                       nargs="+",
                       help=_("show ports to which this application can bind and/or connect"))
    net.set_defaults(func=network)


def communicate(args):
    from sepolicy.communicate import get_types

    writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
    readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
    out = list(set(writable) & set(readable))

    for t in out:
        print t


def gen_communicate_args(parser):
    comm = parser.add_parser("communicate",
                             help=_('query SELinux policy to see if domains can communicate with each other'))
    comm.add_argument("-s", "--source", dest="source",
                      action=CheckDomain, required=True,
                      help=_("Source Domain"))
    comm.add_argument("-t", "--target", dest="target",
                      action=CheckDomain, required=True,
                      help=_("Target Domain"))
    comm.add_argument("-c", "--class", required=False, dest="tclass",
                      action=CheckClass,
                      default="file", help="class to use for communications, Default 'file'")
    comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess", default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'")
    comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess", default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'")
    comm.set_defaults(func=communicate)


def booleans(args):
    from sepolicy import boolean_desc
    if args.all:
        rc, args.booleans = selinux.security_get_boolean_names()
    args.booleans.sort()

    for b in args.booleans:
        print "%s=_(\"%s\")" % (b, boolean_desc(b))


def gen_booleans_args(parser):
    bools = parser.add_parser("booleans",
                              help=_('query SELinux Policy to see description of booleans'))
    group = bools.add_mutually_exclusive_group(required=True)
    group.add_argument("-a", "--all", dest="all", default=False,
                       action="store_true",
                       help=_("get all booleans descriptions"))
    group.add_argument("-b", "--boolean", dest="booleans", nargs="+",
                       action=CheckBoolean, required=False,
                       help=_("boolean to get description"))
    bools.set_defaults(func=booleans)


def transition(args):
    from sepolicy.transition import setrans
    mytrans = setrans(args.source, args.target)
    mytrans.output()


def gen_transition_args(parser):
    trans = parser.add_parser("transition",
                              help=_('query SELinux Policy to see how a source process domain can transition to the target process domain'))
    trans.add_argument("-s", "--source", dest="source",
                       action=CheckDomain, required=True,
                       help=_("source process domain"))
    trans.add_argument("-t", "--target", dest="target",
                       action=CheckDomain,
                       help=_("target process domain"))
    trans.set_defaults(func=transition)


def print_interfaces(interfaces, args, append=""):
    from sepolicy.interface import get_interface_format_text, interface_compile_test
    for i in interfaces:
        if args.verbose:
            try:
                print get_interface_format_text(i + append)
            except KeyError:
                print i
        if args.compile:
            try:
                interface_compile_test(i)
            except KeyError:
                print i
        else:
            print i


def interface(args):
    from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces
    if args.list_admin:
        print_interfaces(get_admin(args.file), args, "_admin")
    if args.list_user:
        print_interfaces(get_user(args.file), args, "_role")
    if args.list:
        print_interfaces(get_all_interfaces(args.file), args)
    if args.interfaces:
        print_interfaces(args.interfaces, args)


def generate(args):
    from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE
    cmd = None
# numbers present POLTYPE defined in sepolicy.generate
    conflict_args = {'TYPES': (NEWTYPE,), 'DOMAIN': (EUSER,), 'ADMIN_DOMAIN': (AUSER, RUSER, EUSER,)}
    error_text = ""

    if args.policytype is None:
        generate_usage = generate_custom_usage(usage, usage_dict)
        for k in usage_dict:
            error_text += "%s" % (k)
        print(generate_usage)
        print(_("sepolicy generate: error: one of the arguments %s is required") % error_text)
        sys.exit(1)

    if args.policytype in APPLICATIONS:
        if not args.command:
            raise ValueError(_("Command required for this type of policy"))
        cmd = os.path.realpath(args.command)
        if not args.name:
            args.name = os.path.basename(cmd).replace("-", "_")

    mypolicy = policy(args.name, args.policytype)
    if cmd:
        mypolicy.set_program(cmd)

    if args.types:
        if args.policytype not in conflict_args['TYPES']:
            raise ValueError(_("-t option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
        mypolicy.set_types(args.types)

    if args.domain:
        if args.policytype not in conflict_args['DOMAIN']:
            raise ValueError(_("-d option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])

    if args.admin_domain:
        if args.policytype not in conflict_args['ADMIN_DOMAIN']:
            raise ValueError(_("-a option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])

    if len(args.writepaths) > 0 and args.policytype == NEWTYPE:

        raise ValueError(_("-w option can not be used with the --newtype option"))

    for p in args.writepaths:
        if os.path.isdir(p):
            mypolicy.add_dir(p)
        else:
            mypolicy.add_file(p)

    mypolicy.set_transition_users(args.user)
    mypolicy.set_admin_roles(args.role)
    mypolicy.set_admin_domains(args.admin_domain)
    mypolicy.set_existing_domains(args.domain)

    if args.policytype in APPLICATIONS:
        mypolicy.gen_writeable()
        mypolicy.gen_symbols()
    print mypolicy.generate(args.path)


def gen_interface_args(parser):
    itf = parser.add_parser("interface",
                            help=_('List SELinux Policy interfaces'))
    itf.add_argument("-c", "--compile", dest="compile",
                     action="store_true", default=False,
                     help="Run compile test for selected interface")
    itf.add_argument("-v", "--verbose", dest="verbose",
                     action="store_true", default=False,
                     help="Show verbose information")
    itf.add_argument("-f", "--file", dest="file",
                     help="Interface file")
    group = itf.add_mutually_exclusive_group(required=True)
    group.add_argument("-a", "--list_admin", dest="list_admin", action="store_true", default=False,
                       help="List all domains with admin interface - DOMAIN_admin()")
    group.add_argument("-u", "--list_user", dest="list_user", action="store_true",
                       default=False,
                       help="List all domains with SELinux user role interface - DOMAIN_role()")
    group.add_argument("-l", "--list", dest="list", action="store_true",
                       default=False,
                       help="List all interfaces")
    group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces",
                       action=InterfaceInfo,
                       help=_("Enter interface names, you wish to query"))
    itf.set_defaults(func=interface)


def gen_generate_args(parser):
    from sepolicy.generate import DAEMON, get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE

    generate_usage = generate_custom_usage(usage, usage_dict)

    pol = parser.add_parser("generate", usage=generate_usage,
                            help=_('Generate SELinux Policy module template'))
    pol.add_argument("-d", "--domain", dest="domain", default=[],
                     action=CheckDomain, nargs="*",
                     help=_("Enter domain type which you will be extending"))
    pol.add_argument("-u", "--user", dest="user", default=[],
                     action=CheckUser,
                     help=_("Enter SELinux user(s) which will transition to this domain"))
    pol.add_argument("-r", "--role", dest="role", default=[],
                     action=CheckRole,
                     help=_("Enter SELinux role(s) to which the administror domain will transition"))
    pol.add_argument("-a", "--admin", dest="admin_domain", default=[],
                     action=CheckAdmin,
                     help=_("Enter domain(s) which this confined admin will administrate"))
    pol.add_argument("-n", "--name", dest="name",
                     default=None,
                     help=_("name of policy to generate"))
    pol.add_argument("-T", "--test", dest="test", default=False, action="store_true",
                     help=argparse.SUPPRESS)
    pol.add_argument("-t", "--type", dest="types", default=[], nargs="*",
                     action=CheckType,
                     help="Enter type(s) for which you will generate new definition and rule(s)")
    pol.add_argument("-p", "--path", dest="path", default=os.getcwd(),
                     help=_("path in which the generated policy files will be stored"))
    pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default=[],
                     help=_("path to which the confined processes will need to write"))
    cmdtype = pol.add_argument_group(_("Policy types which require a command"))
    cmdgroup = cmdtype.add_mutually_exclusive_group(required=False)
    cmdgroup.add_argument("--application", dest="policytype", const=USER,
                          action="store_const",
                          help=_("Generate '%s' policy") % poltype[USER])
    cmdgroup.add_argument("--cgi", dest="policytype", const=CGI,
                          action="store_const",
                          help=_("Generate '%s' policy") % poltype[CGI])
    cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS,
                          action="store_const",
                          help=_("Generate '%s' policy") % poltype[DBUS])
    cmdgroup.add_argument("--inetd", dest="policytype", const=INETD,
                          action="store_const",
                          help=_("Generate '%s' policy") % poltype[INETD])
    cmdgroup.add_argument("--init", dest="policytype", const=DAEMON,
                          action="store_const", default=DAEMON,
                          help=_("Generate '%s' policy") % poltype[DAEMON])

    type = pol.add_argument_group("Policy types which do not require a command")
    group = type.add_mutually_exclusive_group(required=False)
    group.add_argument("--admin_user", dest="policytype", const=AUSER,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[AUSER])
    group.add_argument("--confined_admin", dest="policytype", const=RUSER,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[RUSER])
    group.add_argument("--customize", dest="policytype", const=EUSER,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[EUSER])
    group.add_argument("--desktop_user", dest="policytype", const=LUSER,
                       action="store_const",
                       help=_("Generate '%s' policy ") % poltype[LUSER])
    group.add_argument("--newtype", dest="policytype", const=NEWTYPE,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[NEWTYPE])
    group.add_argument("--sandbox", dest="policytype", const=SANDBOX,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[SANDBOX])
    group.add_argument("--term_user", dest="policytype", const=TUSER,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[TUSER])
    group.add_argument("--x_user", dest="policytype", const=XUSER,
                       action="store_const",
                       help=_("Generate '%s' policy") % poltype[XUSER])
    pol.add_argument("command", nargs="?", default=None,
                     help=_("executable to confine"))
    pol.set_defaults(func=generate)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='SELinux Policy Inspection Tool')
    subparsers = parser.add_subparsers(help=_("commands"))
    parser.add_argument("-P", "--policy", dest="policy",
                        action=LoadPolicy,
                        default=None, help=_("Alternate SELinux policy, defaults to /sys/fs/selinux/policy"))
    gen_booleans_args(subparsers)
    gen_communicate_args(subparsers)
    gen_generate_args(subparsers)
    gen_gui_args(subparsers)
    gen_interface_args(subparsers)
    gen_manpage_args(subparsers)
    gen_network_args(subparsers)
    gen_transition_args(subparsers)

    try:
        if os.path.basename(sys.argv[0]) == "sepolgen":
            args = parser.parse_args(["generate"] + sys.argv[1:])
        else:
            args = parser.parse_args()
        args.func(args)
        sys.exit(0)
    except ValueError, e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
        sys.exit(1)
    except IOError, e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
        sys.exit(1)
    except KeyboardInterrupt:
        print "Out"
        sys.exit(0)
