Home | History | Annotate | Download | only in bin
      1 #!/usr/bin/env 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", action="store_true", help="Search allow and allowxperm rules.")
     37 rtypes.add_argument("--allow", action="append_const",
     38                     const="allow", dest="tertypes",
     39                     help="Search allow rules.")
     40 rtypes.add_argument("--allowxperm", action="append_const",
     41                     const="allowxperm", dest="tertypes",
     42                     help="Search allowxperm rules.")
     43 rtypes.add_argument("--auditallow", action="append_const",
     44                     const="auditallow", dest="tertypes",
     45                     help="Search auditallow rules.")
     46 rtypes.add_argument("--auditallowxperm", action="append_const",
     47                     const="auditallowxperm", dest="tertypes",
     48                     help="Search auditallowxperm rules.")
     49 rtypes.add_argument("--dontaudit", action="append_const",
     50                     const="dontaudit", dest="tertypes",
     51                     help="Search dontaudit rules.")
     52 rtypes.add_argument("--dontauditxperm", action="append_const",
     53                     const="dontauditxperm", dest="tertypes",
     54                     help="Search dontauditxperm rules.")
     55 rtypes.add_argument("--neverallow", action="append_const",
     56                     const="neverallow", dest="tertypes",
     57                     help="Search neverallow rules.")
     58 rtypes.add_argument("--neverallowxperm", action="append_const",
     59                     const="neverallowxperm", dest="tertypes",
     60                     help="Search neverallowxperm rules.")
     61 rtypes.add_argument("-T", "--type_trans", action="append_const",
     62                     const="type_transition", dest="tertypes",
     63                     help="Search type_transition rules.")
     64 rtypes.add_argument("--type_change", action="append_const",
     65                     const="type_change", dest="tertypes",
     66                     help="Search type_change rules.")
     67 rtypes.add_argument("--type_member", action="append_const",
     68                     const="type_member", dest="tertypes",
     69                     help="Search type_member rules.")
     70 rbacrtypes = parser.add_argument_group("RBAC Rule Types")
     71 rbacrtypes.add_argument("--role_allow", action="append_const",
     72                         const="allow", dest="rbacrtypes",
     73                         help="Search role allow rules.")
     74 rbacrtypes.add_argument("--role_trans", action="append_const",
     75                         const="role_transition", dest="rbacrtypes",
     76                         help="Search role_transition rules.")
     77 
     78 mlsrtypes = parser.add_argument_group("MLS Rule Types")
     79 mlsrtypes.add_argument("--range_trans", action="append_const",
     80                        const="range_transition", dest="mlsrtypes",
     81                        help="Search range_transition rules.")
     82 
     83 expr = parser.add_argument_group("Expressions")
     84 expr.add_argument("-s", "--source",
     85                   help="Source type/role of the TE/RBAC rule.")
     86 expr.add_argument("-t", "--target",
     87                   help="Target type/role of the TE/RBAC rule.")
     88 expr.add_argument("-c", "--class", dest="tclass",
     89                   help="Comma separated list of object classes")
     90 expr.add_argument("-p", "--perms", metavar="PERMS",
     91                   help="Comma separated list of permissions.")
     92 expr.add_argument("-x", "--xperms", metavar="XPERMS",
     93                   help="Comma separated list of extended permissions.")
     94 expr.add_argument("-D", "--default",
     95                   help="Default of the rule. (type/role/range transition rules)")
     96 expr.add_argument("-b", "--bool", dest="boolean", metavar="BOOL",
     97                   help="Comma separated list of Booleans in the conditional expression.")
     98 
     99 opts = parser.add_argument_group("Search options")
    100 opts.add_argument("-eb", action="store_true", dest="boolean_equal",
    101                   help="Match Boolean list exactly instead of matching any listed Boolean.")
    102 opts.add_argument("-ep", action="store_true", dest="perms_equal",
    103                   help="Match permission set exactly instead of matching any listed permission.")
    104 opts.add_argument("-ex", action="store_true", dest="xperms_equal",
    105                   help="Match extended permission set exactly instead of matching any listed "
    106                   "permission.")
    107 opts.add_argument("-ds", action="store_false", dest="source_indirect",
    108                   help="Match source attributes directly instead of matching member types/roles.")
    109 opts.add_argument("-dt", action="store_false", dest="target_indirect",
    110                   help="Match target attributes directly instead of matching member types/roles.")
    111 opts.add_argument("-rs", action="store_true", dest="source_regex",
    112                   help="Use regular expression matching for the source type/role.")
    113 opts.add_argument("-rt", action="store_true", dest="target_regex",
    114                   help="Use regular expression matching for the target type/role.")
    115 opts.add_argument("-rc", action="store_true", dest="tclass_regex",
    116                   help="Use regular expression matching for the object class.")
    117 opts.add_argument("-rd", action="store_true", dest="default_regex",
    118                   help="Use regular expression matching for the default type/role.")
    119 opts.add_argument("-rb", action="store_true", dest="boolean_regex",
    120                   help="Use regular expression matching for Booleans.")
    121 
    122 args = parser.parse_args()
    123 
    124 if args.A:
    125     try:
    126         args.tertypes.extend(["allow", "allowxperm"])
    127     except AttributeError:
    128         args.tertypes = ["allow", "allowxperm"]
    129 
    130 if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes:
    131     parser.error("At least one rule type must be specified.")
    132 
    133 if args.debug:
    134     logging.basicConfig(level=logging.DEBUG,
    135                         format='%(asctime)s|%(levelname)s|%(name)s|%(message)s')
    136 elif args.verbose:
    137     logging.basicConfig(level=logging.INFO, format='%(message)s')
    138 else:
    139     logging.basicConfig(level=logging.WARNING, format='%(message)s')
    140 
    141 try:
    142     p = setools.SELinuxPolicy(args.policy)
    143 
    144     if args.tertypes:
    145         q = setools.TERuleQuery(p,
    146                                 ruletype=args.tertypes,
    147                                 source=args.source,
    148                                 source_indirect=args.source_indirect,
    149                                 source_regex=args.source_regex,
    150                                 target=args.target,
    151                                 target_indirect=args.target_indirect,
    152                                 target_regex=args.target_regex,
    153                                 tclass_regex=args.tclass_regex,
    154                                 perms_equal=args.perms_equal,
    155                                 xperms_equal=args.xperms_equal,
    156                                 default=args.default,
    157                                 default_regex=args.default_regex,
    158                                 boolean_regex=args.boolean_regex,
    159                                 boolean_equal=args.boolean_equal)
    160 
    161         # these are broken out from the above statement to prevent making a list
    162         # with an empty string in it (split on empty string)
    163         if args.tclass:
    164             if args.tclass_regex:
    165                 q.tclass = args.tclass
    166             else:
    167                 q.tclass = args.tclass.split(",")
    168 
    169         if args.perms:
    170             q.perms = args.perms.split(",")
    171 
    172         if args.xperms:
    173             xperms = []
    174             for item in args.xperms.split(","):
    175                 rng = item.split("-")
    176                 if len(rng) == 2:
    177                     xperms.append((int(rng[0], base=16), int(rng[1], base=16)))
    178                 elif len(rng) == 1:
    179                     xperms.append((int(rng[0], base=16), int(rng[0], base=16)))
    180                 else:
    181                     parser.error("Enter an extended permission or extended permission range, e.g. "
    182                                  "0x5411 or 0x8800-0x88ff.")
    183 
    184             q.xperms = xperms
    185 
    186         if args.boolean:
    187             if args.boolean_regex:
    188                 q.boolean = args.boolean
    189             else:
    190                 q.boolean = args.boolean.split(",")
    191 
    192         for r in sorted(q.results()):
    193             print(r)
    194 
    195     if args.rbacrtypes:
    196         q = setools.RBACRuleQuery(p,
    197                                   ruletype=args.rbacrtypes,
    198                                   source=args.source,
    199                                   source_indirect=args.source_indirect,
    200                                   source_regex=args.source_regex,
    201                                   target=args.target,
    202                                   target_indirect=args.target_indirect,
    203                                   target_regex=args.target_regex,
    204                                   default=args.default,
    205                                   default_regex=args.default_regex,
    206                                   tclass_regex=args.tclass_regex)
    207 
    208         # these are broken out from the above statement to prevent making a list
    209         # with an empty string in it (split on empty string)
    210         if args.tclass:
    211             if args.tclass_regex:
    212                 q.tclass = args.tclass
    213             else:
    214                 q.tclass = args.tclass.split(",")
    215 
    216         for r in sorted(q.results()):
    217             print(r)
    218 
    219     if args.mlsrtypes:
    220         q = setools.MLSRuleQuery(p,
    221                                  ruletype=args.mlsrtypes,
    222                                  source=args.source,
    223                                  source_indirect=args.source_indirect,
    224                                  source_regex=args.source_regex,
    225                                  target=args.target,
    226                                  target_indirect=args.target_indirect,
    227                                  target_regex=args.target_regex,
    228                                  tclass_regex=args.tclass_regex,
    229                                  default=args.default)
    230 
    231         # these are broken out from the above statement to prevent making a list
    232         # with an empty string in it (split on empty string)
    233         if args.tclass:
    234             if args.tclass_regex:
    235                 q.tclass = args.tclass
    236             else:
    237                 q.tclass = args.tclass.split(",")
    238 
    239         for r in sorted(q.results()):
    240             print(r)
    241 
    242 except Exception as err:
    243     if args.debug:
    244         logging.exception(str(err))
    245     else:
    246         print(err)
    247 
    248     sys.exit(1)
    249