Home | History | Annotate | Download | only in setoolsgui
      1 #!/usr/bin/python
      2 # Copyright 2014-2015, Tresys Technology, LLC
      3 #
      4 # This file is part of SETools.
      5 #
      6 # SETools is free software: you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation, either version 2 of the License, or
      9 # (at your option) any later version.
     10 #
     11 # SETools is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with SETools.  If not, see <http://www.gnu.org/licenses/>.
     18 #
     19 
     20 from __future__ import print_function
     21 import setools
     22 import argparse
     23 import sys
     24 import logging
     25 
     26 parser = argparse.ArgumentParser(
     27     description="SELinux policy rule search tool.",
     28     epilog="TE/MLS rule searches cannot be mixed with RBAC rule searches.")
     29 parser.add_argument("--version", action="version", version=setools.__version__)
     30 parser.add_argument("policy", help="Path to the SELinux policy to search.", nargs="?")
     31 parser.add_argument("-v", "--verbose", action="store_true",
     32                     help="Print extra informational messages")
     33 parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
     34 
     35 rtypes = parser.add_argument_group("TE Rule Types")
     36 rtypes.add_argument("-A", "--allow", action="append_const",
     37                     const="allow", dest="tertypes",
     38                     help="Search allow rules.")
     39 rtypes.add_argument("--auditallow", action="append_const",
     40                     const="auditallow", dest="tertypes",
     41                     help="Search auditallow rules.")
     42 rtypes.add_argument("--dontaudit", action="append_const",
     43                     const="dontaudit", dest="tertypes",
     44                     help="Search dontaudit rules.")
     45 rtypes.add_argument("-T", "--type_trans", action="append_const",
     46                     const="type_transition", dest="tertypes",
     47                     help="Search type_transition rules.")
     48 rtypes.add_argument("--type_change", action="append_const",
     49                     const="type_change", dest="tertypes",
     50                     help="Search type_change rules.")
     51 rtypes.add_argument("--type_member", action="append_const",
     52                     const="type_member", dest="tertypes",
     53                     help="Search type_member rules.")
     54 
     55 rbacrtypes = parser.add_argument_group("RBAC Rule Types")
     56 rbacrtypes.add_argument("--role_allow", action="append_const",
     57                         const="allow", dest="rbacrtypes",
     58                         help="Search role allow rules.")
     59 rbacrtypes.add_argument("--role_trans", action="append_const",
     60                         const="role_transition", dest="rbacrtypes",
     61                         help="Search role_transition rules.")
     62 
     63 mlsrtypes = parser.add_argument_group("MLS Rule Types")
     64 mlsrtypes.add_argument("--range_trans", action="append_const",
     65                        const="range_transition", dest="mlsrtypes",
     66                        help="Search range_transition rules.")
     67 
     68 expr = parser.add_argument_group("Expressions")
     69 expr.add_argument("-s", "--source",
     70                   help="Source type/role of the TE/RBAC rule.")
     71 expr.add_argument("-t", "--target",
     72                   help="Target type/role of the TE/RBAC rule.")
     73 expr.add_argument("-c", "--class", dest="tclass",
     74                   help="Comma separated list of object classes")
     75 expr.add_argument("-p", "--perms", metavar="PERMS",
     76                   help="Comma separated list of permissions.")
     77 expr.add_argument("-D", "--default",
     78                   help="Default of the rule. (type/role/range transition rules)")
     79 expr.add_argument("-b", "--bool", dest="boolean", metavar="BOOL",
     80                   help="Comma separated list of Booleans in the conditional expression.")
     81 
     82 opts = parser.add_argument_group("Search options")
     83 opts.add_argument("-eb", action="store_true", dest="boolean_equal",
     84                   help="Match Boolean list exactly instead of matching any listed Boolean.")
     85 opts.add_argument("-ep", action="store_true", dest="perms_equal",
     86                   help="Match permission set exactly instead of matching any listed permission.")
     87 opts.add_argument("-ds", action="store_false", dest="source_indirect",
     88                   help="Match source attributes directly instead of matching member types/roles.")
     89 opts.add_argument("-dt", action="store_false", dest="target_indirect",
     90                   help="Match target attributes directly instead of matching member types/roles.")
     91 opts.add_argument("-rs", action="store_true", dest="source_regex",
     92                   help="Use regular expression matching for the source type/role.")
     93 opts.add_argument("-rt", action="store_true", dest="target_regex",
     94                   help="Use regular expression matching for the target type/role.")
     95 opts.add_argument("-rc", action="store_true", dest="tclass_regex",
     96                   help="Use regular expression matching for the object class.")
     97 opts.add_argument("-rd", action="store_true", dest="default_regex",
     98                   help="Use regular expression matching for the default type/role.")
     99 opts.add_argument("-rb", action="store_true", dest="boolean_regex",
    100                   help="Use regular expression matching for Booleans.")
    101 
    102 args = parser.parse_args()
    103 
    104 if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes:
    105     parser.error("At least one rule type must be specified.")
    106 
    107 if args.debug:
    108     logging.basicConfig(level=logging.DEBUG,
    109                         format='%(asctime)s|%(levelname)s|%(name)s|%(message)s')
    110 elif args.verbose:
    111     logging.basicConfig(level=logging.INFO, format='%(message)s')
    112 else:
    113     logging.basicConfig(level=logging.WARNING, format='%(message)s')
    114 
    115 try:
    116     p = setools.SELinuxPolicy(args.policy)
    117 
    118     if args.tertypes:
    119         q = setools.TERuleQuery(p,
    120                                 ruletype=args.tertypes,
    121                                 source=args.source,
    122                                 source_indirect=args.source_indirect,
    123                                 source_regex=args.source_regex,
    124                                 target=args.target,
    125                                 target_indirect=args.target_indirect,
    126                                 target_regex=args.target_regex,
    127                                 tclass_regex=args.tclass_regex,
    128                                 perms_equal=args.perms_equal,
    129                                 default=args.default,
    130                                 default_regex=args.default_regex,
    131                                 boolean_regex=args.boolean_regex,
    132                                 boolean_equal=args.boolean_equal)
    133 
    134         # these are broken out from the above statement to prevent making a list
    135         # with an empty string in it (split on empty string)
    136         if args.tclass:
    137             if args.tclass_regex:
    138                 q.tclass = args.tclass
    139             else:
    140                 q.tclass = args.tclass.split(",")
    141 
    142         if args.perms:
    143             q.perms = args.perms.split(",")
    144 
    145         if args.boolean:
    146             if args.boolean_regex:
    147                 q.boolean = args.boolean
    148             else:
    149                 q.boolean = args.boolean.split(",")
    150 
    151         for r in sorted(q.results()):
    152             print(r)
    153 
    154     if args.rbacrtypes:
    155         q = setools.RBACRuleQuery(p,
    156                                   ruletype=args.rbacrtypes,
    157                                   source=args.source,
    158                                   source_indirect=args.source_indirect,
    159                                   source_regex=args.source_regex,
    160                                   target=args.target,
    161                                   target_indirect=args.target_indirect,
    162                                   target_regex=args.target_regex,
    163                                   default=args.default,
    164                                   default_regex=args.default_regex,
    165                                   tclass_regex=args.tclass_regex)
    166 
    167         # these are broken out from the above statement to prevent making a list
    168         # with an empty string in it (split on empty string)
    169         if args.tclass:
    170             if args.tclass_regex:
    171                 q.tclass = args.tclass
    172             else:
    173                 q.tclass = args.tclass.split(",")
    174 
    175         for r in sorted(q.results()):
    176             print(r)
    177 
    178     if args.mlsrtypes:
    179         q = setools.MLSRuleQuery(p,
    180                                  ruletype=args.mlsrtypes,
    181                                  source=args.source,
    182                                  source_regex=args.source_regex,
    183                                  target=args.target,
    184                                  target_regex=args.target_regex,
    185                                  tclass_regex=args.tclass_regex,
    186                                  default=args.default)
    187 
    188         # these are broken out from the above statement to prevent making a list
    189         # with an empty string in it (split on empty string)
    190         if args.tclass:
    191             if args.tclass_regex:
    192                 q.tclass = args.tclass
    193             else:
    194                 q.tclass = args.tclass.split(",")
    195 
    196         for r in sorted(q.results()):
    197             print(r)
    198 
    199 except Exception as err:
    200     if args.debug:
    201         import traceback
    202         traceback.print_exc()
    203     else:
    204         print(err)
    205 
    206     sys.exit(-1)
    207