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 20from __future__ import print_function 21import setools 22import argparse 23import sys 24import logging 25 26parser = argparse.ArgumentParser( 27 description="SELinux policy rule search tool.", 28 epilog="TE/MLS rule searches cannot be mixed with RBAC rule searches.") 29parser.add_argument("--version", action="version", version=setools.__version__) 30parser.add_argument("policy", help="Path to the SELinux policy to search.", nargs="?") 31parser.add_argument("-v", "--verbose", action="store_true", 32 help="Print extra informational messages") 33parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.") 34 35rtypes = parser.add_argument_group("TE Rule Types") 36rtypes.add_argument("-A", action="store_true", help="Search allow and allowxperm rules.") 37rtypes.add_argument("--allow", action="append_const", 38 const="allow", dest="tertypes", 39 help="Search allow rules.") 40rtypes.add_argument("--allowxperm", action="append_const", 41 const="allowxperm", dest="tertypes", 42 help="Search allowxperm rules.") 43rtypes.add_argument("--auditallow", action="append_const", 44 const="auditallow", dest="tertypes", 45 help="Search auditallow rules.") 46rtypes.add_argument("--auditallowxperm", action="append_const", 47 const="auditallowxperm", dest="tertypes", 48 help="Search auditallowxperm rules.") 49rtypes.add_argument("--dontaudit", action="append_const", 50 const="dontaudit", dest="tertypes", 51 help="Search dontaudit rules.") 52rtypes.add_argument("--dontauditxperm", action="append_const", 53 const="dontauditxperm", dest="tertypes", 54 help="Search dontauditxperm rules.") 55rtypes.add_argument("--neverallow", action="append_const", 56 const="neverallow", dest="tertypes", 57 help="Search neverallow rules.") 58rtypes.add_argument("--neverallowxperm", action="append_const", 59 const="neverallowxperm", dest="tertypes", 60 help="Search neverallowxperm rules.") 61rtypes.add_argument("-T", "--type_trans", action="append_const", 62 const="type_transition", dest="tertypes", 63 help="Search type_transition rules.") 64rtypes.add_argument("--type_change", action="append_const", 65 const="type_change", dest="tertypes", 66 help="Search type_change rules.") 67rtypes.add_argument("--type_member", action="append_const", 68 const="type_member", dest="tertypes", 69 help="Search type_member rules.") 70rbacrtypes = parser.add_argument_group("RBAC Rule Types") 71rbacrtypes.add_argument("--role_allow", action="append_const", 72 const="allow", dest="rbacrtypes", 73 help="Search role allow rules.") 74rbacrtypes.add_argument("--role_trans", action="append_const", 75 const="role_transition", dest="rbacrtypes", 76 help="Search role_transition rules.") 77 78mlsrtypes = parser.add_argument_group("MLS Rule Types") 79mlsrtypes.add_argument("--range_trans", action="append_const", 80 const="range_transition", dest="mlsrtypes", 81 help="Search range_transition rules.") 82 83expr = parser.add_argument_group("Expressions") 84expr.add_argument("-s", "--source", 85 help="Source type/role of the TE/RBAC rule.") 86expr.add_argument("-t", "--target", 87 help="Target type/role of the TE/RBAC rule.") 88expr.add_argument("-c", "--class", dest="tclass", 89 help="Comma separated list of object classes") 90expr.add_argument("-p", "--perms", metavar="PERMS", 91 help="Comma separated list of permissions.") 92expr.add_argument("-x", "--xperms", metavar="XPERMS", 93 help="Comma separated list of extended permissions.") 94expr.add_argument("-D", "--default", 95 help="Default of the rule. (type/role/range transition rules)") 96expr.add_argument("-b", "--bool", dest="boolean", metavar="BOOL", 97 help="Comma separated list of Booleans in the conditional expression.") 98 99opts = parser.add_argument_group("Search options") 100opts.add_argument("-eb", action="store_true", dest="boolean_equal", 101 help="Match Boolean list exactly instead of matching any listed Boolean.") 102opts.add_argument("-ep", action="store_true", dest="perms_equal", 103 help="Match permission set exactly instead of matching any listed permission.") 104opts.add_argument("-ex", action="store_true", dest="xperms_equal", 105 help="Match extended permission set exactly instead of matching any listed " 106 "permission.") 107opts.add_argument("-ds", action="store_false", dest="source_indirect", 108 help="Match source attributes directly instead of matching member types/roles.") 109opts.add_argument("-dt", action="store_false", dest="target_indirect", 110 help="Match target attributes directly instead of matching member types/roles.") 111opts.add_argument("-rs", action="store_true", dest="source_regex", 112 help="Use regular expression matching for the source type/role.") 113opts.add_argument("-rt", action="store_true", dest="target_regex", 114 help="Use regular expression matching for the target type/role.") 115opts.add_argument("-rc", action="store_true", dest="tclass_regex", 116 help="Use regular expression matching for the object class.") 117opts.add_argument("-rd", action="store_true", dest="default_regex", 118 help="Use regular expression matching for the default type/role.") 119opts.add_argument("-rb", action="store_true", dest="boolean_regex", 120 help="Use regular expression matching for Booleans.") 121 122args = parser.parse_args() 123 124if args.A: 125 try: 126 args.tertypes.extend(["allow", "allowxperm"]) 127 except AttributeError: 128 args.tertypes = ["allow", "allowxperm"] 129 130if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes: 131 parser.error("At least one rule type must be specified.") 132 133if args.debug: 134 logging.basicConfig(level=logging.DEBUG, 135 format='%(asctime)s|%(levelname)s|%(name)s|%(message)s') 136elif args.verbose: 137 logging.basicConfig(level=logging.INFO, format='%(message)s') 138else: 139 logging.basicConfig(level=logging.WARNING, format='%(message)s') 140 141try: 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 242except Exception as err: 243 if args.debug: 244 logging.exception(str(err)) 245 else: 246 print(err) 247 248 sys.exit(1) 249