• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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