xref: /aosp_15_r20/external/selinux/python/sepolicy/sepolicy.py (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker#!/usr/bin/python3 -EsI
2*2d543d20SAndroid Build Coastguard Worker# Copyright (C) 2012 Red Hat
3*2d543d20SAndroid Build Coastguard Worker# AUTHOR: Dan Walsh <[email protected]>
4*2d543d20SAndroid Build Coastguard Worker# see file 'COPYING' for use and warranty information
5*2d543d20SAndroid Build Coastguard Worker#
6*2d543d20SAndroid Build Coastguard Worker# semanage is a tool for managing SELinux configuration files
7*2d543d20SAndroid Build Coastguard Worker#
8*2d543d20SAndroid Build Coastguard Worker#    This program is free software; you can redistribute it and/or
9*2d543d20SAndroid Build Coastguard Worker#    modify it under the terms of the GNU General Public License as
10*2d543d20SAndroid Build Coastguard Worker#    published by the Free Software Foundation; either version 2 of
11*2d543d20SAndroid Build Coastguard Worker#    the License, or (at your option) any later version.
12*2d543d20SAndroid Build Coastguard Worker#
13*2d543d20SAndroid Build Coastguard Worker#    This program is distributed in the hope that it will be useful,
14*2d543d20SAndroid Build Coastguard Worker#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*2d543d20SAndroid Build Coastguard Worker#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*2d543d20SAndroid Build Coastguard Worker#    GNU General Public License for more details.
17*2d543d20SAndroid Build Coastguard Worker#
18*2d543d20SAndroid Build Coastguard Worker#    You should have received a copy of the GNU General Public License
19*2d543d20SAndroid Build Coastguard Worker#    along with this program; if not, write to the Free Software
20*2d543d20SAndroid Build Coastguard Worker#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21*2d543d20SAndroid Build Coastguard Worker#                                        02111-1307  USA
22*2d543d20SAndroid Build Coastguard Worker#
23*2d543d20SAndroid Build Coastguard Worker#
24*2d543d20SAndroid Build Coastguard Workerimport os
25*2d543d20SAndroid Build Coastguard Workerimport sys
26*2d543d20SAndroid Build Coastguard Workerimport selinux
27*2d543d20SAndroid Build Coastguard Workerimport sepolicy
28*2d543d20SAndroid Build Coastguard Workerfrom multiprocessing import Pool
29*2d543d20SAndroid Build Coastguard Workerfrom sepolicy import get_os_version, get_conditionals, get_conditionals_format_text
30*2d543d20SAndroid Build Coastguard Workerimport argparse
31*2d543d20SAndroid Build Coastguard WorkerPROGNAME = "selinux-python"
32*2d543d20SAndroid Build Coastguard Workertry:
33*2d543d20SAndroid Build Coastguard Worker    import gettext
34*2d543d20SAndroid Build Coastguard Worker    kwargs = {}
35*2d543d20SAndroid Build Coastguard Worker    if sys.version_info < (3,):
36*2d543d20SAndroid Build Coastguard Worker        kwargs['unicode'] = True
37*2d543d20SAndroid Build Coastguard Worker    t = gettext.translation(PROGNAME,
38*2d543d20SAndroid Build Coastguard Worker                    localedir="/usr/share/locale",
39*2d543d20SAndroid Build Coastguard Worker                    **kwargs,
40*2d543d20SAndroid Build Coastguard Worker                    fallback=True)
41*2d543d20SAndroid Build Coastguard Worker    _ = t.gettext
42*2d543d20SAndroid Build Coastguard Workerexcept:
43*2d543d20SAndroid Build Coastguard Worker    try:
44*2d543d20SAndroid Build Coastguard Worker        import builtins
45*2d543d20SAndroid Build Coastguard Worker        builtins.__dict__['_'] = str
46*2d543d20SAndroid Build Coastguard Worker    except ImportError:
47*2d543d20SAndroid Build Coastguard Worker        import __builtin__
48*2d543d20SAndroid Build Coastguard Worker        __builtin__.__dict__['_'] = unicode
49*2d543d20SAndroid Build Coastguard Worker
50*2d543d20SAndroid Build Coastguard Workerusage = "sepolicy generate [-h] [-n NAME] [-p PATH] ["
51*2d543d20SAndroid Build Coastguard Workerusage_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 ]",)}
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker
54*2d543d20SAndroid Build Coastguard Workerclass CheckPath(argparse.Action):
55*2d543d20SAndroid Build Coastguard Worker
56*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
57*2d543d20SAndroid Build Coastguard Worker        if not os.path.exists(values):
58*2d543d20SAndroid Build Coastguard Worker            raise ValueError("%s does not exist" % values)
59*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, values)
60*2d543d20SAndroid Build Coastguard Worker
61*2d543d20SAndroid Build Coastguard Worker
62*2d543d20SAndroid Build Coastguard Workerclass CheckType(argparse.Action):
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
65*2d543d20SAndroid Build Coastguard Worker        if isinstance(values, str):
66*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, values)
67*2d543d20SAndroid Build Coastguard Worker        else:
68*2d543d20SAndroid Build Coastguard Worker            newval = getattr(namespace, self.dest)
69*2d543d20SAndroid Build Coastguard Worker            if not newval:
70*2d543d20SAndroid Build Coastguard Worker                newval = []
71*2d543d20SAndroid Build Coastguard Worker
72*2d543d20SAndroid Build Coastguard Worker            for v in values:
73*2d543d20SAndroid Build Coastguard Worker                newval.append(v)
74*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, newval)
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Worker
77*2d543d20SAndroid Build Coastguard Workerclass CheckBoolean(argparse.Action):
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
80*2d543d20SAndroid Build Coastguard Worker        booleans = sepolicy.get_all_booleans()
81*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
82*2d543d20SAndroid Build Coastguard Worker        if not newval:
83*2d543d20SAndroid Build Coastguard Worker            newval = []
84*2d543d20SAndroid Build Coastguard Worker
85*2d543d20SAndroid Build Coastguard Worker        if isinstance(values, str):
86*2d543d20SAndroid Build Coastguard Worker            v = selinux.selinux_boolean_sub(values)
87*2d543d20SAndroid Build Coastguard Worker            if v not in booleans:
88*2d543d20SAndroid Build Coastguard Worker                raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans)))
89*2d543d20SAndroid Build Coastguard Worker            newval.append(v)
90*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, newval)
91*2d543d20SAndroid Build Coastguard Worker        else:
92*2d543d20SAndroid Build Coastguard Worker            for value in values:
93*2d543d20SAndroid Build Coastguard Worker                v = selinux.selinux_boolean_sub(value)
94*2d543d20SAndroid Build Coastguard Worker                if v not in booleans:
95*2d543d20SAndroid Build Coastguard Worker                    raise ValueError("%s must be an SELinux boolean:\nValid boolean: %s" % (v, ", ".join(booleans)))
96*2d543d20SAndroid Build Coastguard Worker                newval.append(v)
97*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, newval)
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker
100*2d543d20SAndroid Build Coastguard Workerclass CheckDomain(argparse.Action):
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
103*2d543d20SAndroid Build Coastguard Worker        domains = sepolicy.get_all_domains()
104*2d543d20SAndroid Build Coastguard Worker
105*2d543d20SAndroid Build Coastguard Worker        if isinstance(values, str):
106*2d543d20SAndroid Build Coastguard Worker            values = sepolicy.get_real_type_name(values)
107*2d543d20SAndroid Build Coastguard Worker            if values not in domains:
108*2d543d20SAndroid Build Coastguard Worker                raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains)))
109*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, values)
110*2d543d20SAndroid Build Coastguard Worker        else:
111*2d543d20SAndroid Build Coastguard Worker            newval = getattr(namespace, self.dest)
112*2d543d20SAndroid Build Coastguard Worker            if not newval:
113*2d543d20SAndroid Build Coastguard Worker                newval = []
114*2d543d20SAndroid Build Coastguard Worker
115*2d543d20SAndroid Build Coastguard Worker            for v in values:
116*2d543d20SAndroid Build Coastguard Worker                v = sepolicy.get_real_type_name(v)
117*2d543d20SAndroid Build Coastguard Worker                if v not in domains:
118*2d543d20SAndroid Build Coastguard Worker                    raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(domains)))
119*2d543d20SAndroid Build Coastguard Worker                newval.append(v)
120*2d543d20SAndroid Build Coastguard Worker            setattr(namespace, self.dest, newval)
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Workerall_classes = None
123*2d543d20SAndroid Build Coastguard Worker
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Workerclass CheckClass(argparse.Action):
126*2d543d20SAndroid Build Coastguard Worker
127*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
128*2d543d20SAndroid Build Coastguard Worker        global all_classes
129*2d543d20SAndroid Build Coastguard Worker        if not all_classes:
130*2d543d20SAndroid Build Coastguard Worker            all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
131*2d543d20SAndroid Build Coastguard Worker        if values not in all_classes:
132*2d543d20SAndroid Build Coastguard Worker            raise ValueError("%s must be an SELinux class:\nValid classes: %s" % (values, ", ".join(all_classes)))
133*2d543d20SAndroid Build Coastguard Worker
134*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, values)
135*2d543d20SAndroid Build Coastguard Worker
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Workerclass CheckAdmin(argparse.Action):
138*2d543d20SAndroid Build Coastguard Worker
139*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
140*2d543d20SAndroid Build Coastguard Worker        from sepolicy.interface import get_admin
141*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
142*2d543d20SAndroid Build Coastguard Worker        if not newval:
143*2d543d20SAndroid Build Coastguard Worker            newval = []
144*2d543d20SAndroid Build Coastguard Worker        admins = get_admin()
145*2d543d20SAndroid Build Coastguard Worker        if values not in admins:
146*2d543d20SAndroid Build Coastguard Worker            raise ValueError("%s must be an SELinux admin domain:\nValid admin domains: %s" % (values, ", ".join(admins)))
147*2d543d20SAndroid Build Coastguard Worker        newval.append(values)
148*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, newval)
149*2d543d20SAndroid Build Coastguard Worker
150*2d543d20SAndroid Build Coastguard Worker
151*2d543d20SAndroid Build Coastguard Workerclass CheckPort(argparse.Action):
152*2d543d20SAndroid Build Coastguard Worker
153*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
154*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
155*2d543d20SAndroid Build Coastguard Worker        if not newval:
156*2d543d20SAndroid Build Coastguard Worker            newval = []
157*2d543d20SAndroid Build Coastguard Worker        for v in values:
158*2d543d20SAndroid Build Coastguard Worker            if v < 1 or v > 65536:
159*2d543d20SAndroid Build Coastguard Worker                raise ValueError("%s must be an integer between 1 and 65536" % v)
160*2d543d20SAndroid Build Coastguard Worker            newval.append(v)
161*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, newval)
162*2d543d20SAndroid Build Coastguard Worker
163*2d543d20SAndroid Build Coastguard Worker
164*2d543d20SAndroid Build Coastguard Workerclass CheckPortType(argparse.Action):
165*2d543d20SAndroid Build Coastguard Worker
166*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
167*2d543d20SAndroid Build Coastguard Worker        port_types = sepolicy.get_all_port_types()
168*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
169*2d543d20SAndroid Build Coastguard Worker        if not newval:
170*2d543d20SAndroid Build Coastguard Worker            newval = []
171*2d543d20SAndroid Build Coastguard Worker        for v in values:
172*2d543d20SAndroid Build Coastguard Worker            v = sepolicy.get_real_type_name(v)
173*2d543d20SAndroid Build Coastguard Worker            if v not in port_types:
174*2d543d20SAndroid Build Coastguard Worker                raise ValueError("%s must be an SELinux port type:\nValid port types: %s" % (v, ", ".join(port_types)))
175*2d543d20SAndroid Build Coastguard Worker            newval.append(v)
176*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, newval)
177*2d543d20SAndroid Build Coastguard Worker
178*2d543d20SAndroid Build Coastguard Worker
179*2d543d20SAndroid Build Coastguard Workerclass LoadPolicy(argparse.Action):
180*2d543d20SAndroid Build Coastguard Worker
181*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
182*2d543d20SAndroid Build Coastguard Worker        import sepolicy
183*2d543d20SAndroid Build Coastguard Worker        sepolicy.policy(values)
184*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, values)
185*2d543d20SAndroid Build Coastguard Worker
186*2d543d20SAndroid Build Coastguard Worker
187*2d543d20SAndroid Build Coastguard Workerclass CheckUser(argparse.Action):
188*2d543d20SAndroid Build Coastguard Worker
189*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, value, option_string=None):
190*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
191*2d543d20SAndroid Build Coastguard Worker        if not newval:
192*2d543d20SAndroid Build Coastguard Worker            newval = []
193*2d543d20SAndroid Build Coastguard Worker        users = sepolicy.get_all_users()
194*2d543d20SAndroid Build Coastguard Worker        if value not in users:
195*2d543d20SAndroid Build Coastguard Worker            raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
196*2d543d20SAndroid Build Coastguard Worker        newval.append(value)
197*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, newval)
198*2d543d20SAndroid Build Coastguard Worker
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Workerclass CheckRole(argparse.Action):
201*2d543d20SAndroid Build Coastguard Worker
202*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, value, option_string=None):
203*2d543d20SAndroid Build Coastguard Worker        newval = getattr(namespace, self.dest)
204*2d543d20SAndroid Build Coastguard Worker        if not newval:
205*2d543d20SAndroid Build Coastguard Worker            newval = []
206*2d543d20SAndroid Build Coastguard Worker        roles = sepolicy.get_all_roles()
207*2d543d20SAndroid Build Coastguard Worker        if value not in roles:
208*2d543d20SAndroid Build Coastguard Worker            raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
209*2d543d20SAndroid Build Coastguard Worker        newval.append(value[:-2])
210*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, newval)
211*2d543d20SAndroid Build Coastguard Worker
212*2d543d20SAndroid Build Coastguard Worker
213*2d543d20SAndroid Build Coastguard Workerclass InterfaceInfo(argparse.Action):
214*2d543d20SAndroid Build Coastguard Worker
215*2d543d20SAndroid Build Coastguard Worker    def __call__(self, parser, namespace, values, option_string=None):
216*2d543d20SAndroid Build Coastguard Worker        from sepolicy.interface import get_interface_dict
217*2d543d20SAndroid Build Coastguard Worker        interface_dict = get_interface_dict()
218*2d543d20SAndroid Build Coastguard Worker        for v in values:
219*2d543d20SAndroid Build Coastguard Worker            if v not in interface_dict.keys():
220*2d543d20SAndroid Build Coastguard Worker                raise ValueError(_("Interface %s does not exist.") % v)
221*2d543d20SAndroid Build Coastguard Worker
222*2d543d20SAndroid Build Coastguard Worker        setattr(namespace, self.dest, values)
223*2d543d20SAndroid Build Coastguard Worker
224*2d543d20SAndroid Build Coastguard Worker
225*2d543d20SAndroid Build Coastguard Workerdef generate_custom_usage(usage_text, usage_dict):
226*2d543d20SAndroid Build Coastguard Worker    sorted_keys = []
227*2d543d20SAndroid Build Coastguard Worker    for i in usage_dict.keys():
228*2d543d20SAndroid Build Coastguard Worker        sorted_keys.append(i)
229*2d543d20SAndroid Build Coastguard Worker    sorted_keys.sort()
230*2d543d20SAndroid Build Coastguard Worker    for k in sorted_keys:
231*2d543d20SAndroid Build Coastguard Worker        usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
232*2d543d20SAndroid Build Coastguard Worker    usage_text = usage_text[:-1] + "]"
233*2d543d20SAndroid Build Coastguard Worker    usage_text = _(usage_text)
234*2d543d20SAndroid Build Coastguard Worker
235*2d543d20SAndroid Build Coastguard Worker    return usage_text
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker# expects formats:
238*2d543d20SAndroid Build Coastguard Worker# "22 (sshd_t)", "80, 8080 (httpd_t)", "all ports (port_type)"
239*2d543d20SAndroid Build Coastguard Workerdef port_string_to_num(val):
240*2d543d20SAndroid Build Coastguard Worker    try:
241*2d543d20SAndroid Build Coastguard Worker        return int(val.split(" ")[0].split(",")[0].split("-")[0])
242*2d543d20SAndroid Build Coastguard Worker    except:
243*2d543d20SAndroid Build Coastguard Worker        return 99999999
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Worker
246*2d543d20SAndroid Build Coastguard Workerdef _print_net(src, protocol, perm):
247*2d543d20SAndroid Build Coastguard Worker    import sepolicy.network
248*2d543d20SAndroid Build Coastguard Worker    portdict = sepolicy.network.get_network_connect(src, protocol, perm)
249*2d543d20SAndroid Build Coastguard Worker    if len(portdict) > 0:
250*2d543d20SAndroid Build Coastguard Worker        bold_start = "\033[1m"
251*2d543d20SAndroid Build Coastguard Worker        bold_end = "\033[0;0m"
252*2d543d20SAndroid Build Coastguard Worker        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
253*2d543d20SAndroid Build Coastguard Worker        port_strings = []
254*2d543d20SAndroid Build Coastguard Worker        boolean_text = ""
255*2d543d20SAndroid Build Coastguard Worker        for p in portdict:
256*2d543d20SAndroid Build Coastguard Worker            for t, recs in portdict[p]:
257*2d543d20SAndroid Build Coastguard Worker                cond = get_conditionals(src, t, "%s_socket" % protocol, [perm])
258*2d543d20SAndroid Build Coastguard Worker                if cond:
259*2d543d20SAndroid Build Coastguard Worker                    boolean_text = get_conditionals_format_text(cond)
260*2d543d20SAndroid Build Coastguard Worker                    port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text))
261*2d543d20SAndroid Build Coastguard Worker                else:
262*2d543d20SAndroid Build Coastguard Worker                    port_strings.append("%s (%s)" % (", ".join(recs), t))
263*2d543d20SAndroid Build Coastguard Worker        port_strings.sort(key=lambda param: port_string_to_num(param))
264*2d543d20SAndroid Build Coastguard Worker        for p in port_strings:
265*2d543d20SAndroid Build Coastguard Worker            print("\t" + p)
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker
268*2d543d20SAndroid Build Coastguard Workerdef network(args):
269*2d543d20SAndroid Build Coastguard Worker    portrecs, portrecsbynum = sepolicy.gen_port_dict()
270*2d543d20SAndroid Build Coastguard Worker    all_ports = []
271*2d543d20SAndroid Build Coastguard Worker    if args.list_ports:
272*2d543d20SAndroid Build Coastguard Worker        for i in portrecs:
273*2d543d20SAndroid Build Coastguard Worker            if i[0] not in all_ports:
274*2d543d20SAndroid Build Coastguard Worker                all_ports.append(i[0])
275*2d543d20SAndroid Build Coastguard Worker        all_ports.sort()
276*2d543d20SAndroid Build Coastguard Worker        print("\n".join(all_ports))
277*2d543d20SAndroid Build Coastguard Worker
278*2d543d20SAndroid Build Coastguard Worker    for port in args.port:
279*2d543d20SAndroid Build Coastguard Worker        found = False
280*2d543d20SAndroid Build Coastguard Worker        for i in portrecsbynum:
281*2d543d20SAndroid Build Coastguard Worker            if i[0] <= port and port <= i[1]:
282*2d543d20SAndroid Build Coastguard Worker                if i[0] == i[1]:
283*2d543d20SAndroid Build Coastguard Worker                    range = i[0]
284*2d543d20SAndroid Build Coastguard Worker                else:
285*2d543d20SAndroid Build Coastguard Worker                    range = "%s-%s" % (i[0], i[1])
286*2d543d20SAndroid Build Coastguard Worker                found = True
287*2d543d20SAndroid Build Coastguard Worker                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
288*2d543d20SAndroid Build Coastguard Worker        if not found:
289*2d543d20SAndroid Build Coastguard Worker            if port < 500:
290*2d543d20SAndroid Build Coastguard Worker                print("Undefined reserved port type")
291*2d543d20SAndroid Build Coastguard Worker            else:
292*2d543d20SAndroid Build Coastguard Worker                print("Undefined port type")
293*2d543d20SAndroid Build Coastguard Worker
294*2d543d20SAndroid Build Coastguard Worker    for t in args.type:
295*2d543d20SAndroid Build Coastguard Worker        if (t, 'tcp') in portrecs.keys():
296*2d543d20SAndroid Build Coastguard Worker            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
297*2d543d20SAndroid Build Coastguard Worker        if (t, 'udp') in portrecs.keys():
298*2d543d20SAndroid Build Coastguard Worker            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
299*2d543d20SAndroid Build Coastguard Worker
300*2d543d20SAndroid Build Coastguard Worker    for a in args.applications:
301*2d543d20SAndroid Build Coastguard Worker        d = sepolicy.get_init_transtype(a)
302*2d543d20SAndroid Build Coastguard Worker        if d:
303*2d543d20SAndroid Build Coastguard Worker            args.domain.append(d)
304*2d543d20SAndroid Build Coastguard Worker
305*2d543d20SAndroid Build Coastguard Worker    for d in args.domain:
306*2d543d20SAndroid Build Coastguard Worker        _print_net(d, "tcp", "name_connect")
307*2d543d20SAndroid Build Coastguard Worker        for net in ("tcp", "udp"):
308*2d543d20SAndroid Build Coastguard Worker            _print_net(d, net, "name_bind")
309*2d543d20SAndroid Build Coastguard Worker
310*2d543d20SAndroid Build Coastguard Worker
311*2d543d20SAndroid Build Coastguard Workerdef gui_run(args):
312*2d543d20SAndroid Build Coastguard Worker    try:
313*2d543d20SAndroid Build Coastguard Worker        import sepolicy.gui
314*2d543d20SAndroid Build Coastguard Worker        sepolicy.gui.SELinuxGui(args.domain, args.test)
315*2d543d20SAndroid Build Coastguard Worker        pass
316*2d543d20SAndroid Build Coastguard Worker    except ImportError:
317*2d543d20SAndroid Build Coastguard Worker        raise ValueError(_("You need to install policycoreutils-gui package to use the gui option"))
318*2d543d20SAndroid Build Coastguard Worker
319*2d543d20SAndroid Build Coastguard Worker
320*2d543d20SAndroid Build Coastguard Workerdef gen_gui_args(parser):
321*2d543d20SAndroid Build Coastguard Worker    gui = parser.add_parser("gui",
322*2d543d20SAndroid Build Coastguard Worker                            help=_('Graphical User Interface for SELinux Policy'))
323*2d543d20SAndroid Build Coastguard Worker    gui.add_argument("-d", "--domain", default=None,
324*2d543d20SAndroid Build Coastguard Worker                     action=CheckDomain,
325*2d543d20SAndroid Build Coastguard Worker                     help=_("Domain name(s) of man pages to be created"))
326*2d543d20SAndroid Build Coastguard Worker    gui.add_argument("-t", "--test", default=False, action="store_true",
327*2d543d20SAndroid Build Coastguard Worker                     help=argparse.SUPPRESS)
328*2d543d20SAndroid Build Coastguard Worker    gui.set_defaults(func=gui_run)
329*2d543d20SAndroid Build Coastguard Worker
330*2d543d20SAndroid Build Coastguard Worker
331*2d543d20SAndroid Build Coastguard Workerdef manpage_work(domain, path, root, source_files, web):
332*2d543d20SAndroid Build Coastguard Worker    from sepolicy.manpage import ManPage
333*2d543d20SAndroid Build Coastguard Worker    m = ManPage(domain, path, root, source_files, web)
334*2d543d20SAndroid Build Coastguard Worker    print(m.get_man_page_path())
335*2d543d20SAndroid Build Coastguard Worker    return (m.manpage_domains, m.manpage_roles)
336*2d543d20SAndroid Build Coastguard Worker
337*2d543d20SAndroid Build Coastguard Workerdef manpage(args):
338*2d543d20SAndroid Build Coastguard Worker    from sepolicy.manpage import HTMLManPages, gen_domains
339*2d543d20SAndroid Build Coastguard Worker
340*2d543d20SAndroid Build Coastguard Worker    path = args.path
341*2d543d20SAndroid Build Coastguard Worker    if not args.policy and args.root != "/":
342*2d543d20SAndroid Build Coastguard Worker        sepolicy.policy(sepolicy.get_installed_policy(args.root))
343*2d543d20SAndroid Build Coastguard Worker    if args.source_files and args.root == "/":
344*2d543d20SAndroid Build Coastguard Worker        raise ValueError(_("Alternative root needs to be setup"))
345*2d543d20SAndroid Build Coastguard Worker
346*2d543d20SAndroid Build Coastguard Worker    if args.all:
347*2d543d20SAndroid Build Coastguard Worker        test_domains = gen_domains()
348*2d543d20SAndroid Build Coastguard Worker    else:
349*2d543d20SAndroid Build Coastguard Worker        test_domains = args.domain
350*2d543d20SAndroid Build Coastguard Worker
351*2d543d20SAndroid Build Coastguard Worker    manpage_domains = set()
352*2d543d20SAndroid Build Coastguard Worker    manpage_roles = set()
353*2d543d20SAndroid Build Coastguard Worker    p = Pool()
354*2d543d20SAndroid Build Coastguard Worker    async_results = []
355*2d543d20SAndroid Build Coastguard Worker    for domain in test_domains:
356*2d543d20SAndroid Build Coastguard Worker        async_results.append(p.apply_async(manpage_work, [domain, path, args.root, args.source_files, args.web]))
357*2d543d20SAndroid Build Coastguard Worker    for result in async_results:
358*2d543d20SAndroid Build Coastguard Worker        domains, roles = result.get()
359*2d543d20SAndroid Build Coastguard Worker        manpage_domains.update(domains)
360*2d543d20SAndroid Build Coastguard Worker        manpage_roles.update(roles)
361*2d543d20SAndroid Build Coastguard Worker
362*2d543d20SAndroid Build Coastguard Worker    p.close()
363*2d543d20SAndroid Build Coastguard Worker    p.join()
364*2d543d20SAndroid Build Coastguard Worker
365*2d543d20SAndroid Build Coastguard Worker    if args.web:
366*2d543d20SAndroid Build Coastguard Worker        HTMLManPages(manpage_roles, manpage_domains, path, args.os)
367*2d543d20SAndroid Build Coastguard Worker
368*2d543d20SAndroid Build Coastguard Worker
369*2d543d20SAndroid Build Coastguard Workerdef gen_manpage_args(parser):
370*2d543d20SAndroid Build Coastguard Worker    man = parser.add_parser("manpage",
371*2d543d20SAndroid Build Coastguard Worker                            help=_('Generate SELinux man pages'))
372*2d543d20SAndroid Build Coastguard Worker
373*2d543d20SAndroid Build Coastguard Worker    man.add_argument("-p", "--path", dest="path", default="/tmp",
374*2d543d20SAndroid Build Coastguard Worker                     help=_("path in which the generated SELinux man pages will be stored"))
375*2d543d20SAndroid Build Coastguard Worker    man.add_argument("-o", "--os", dest="os", default=get_os_version(),
376*2d543d20SAndroid Build Coastguard Worker                     help=_("name of the OS for man pages"))
377*2d543d20SAndroid Build Coastguard Worker    man.add_argument("-w", "--web", dest="web", default=False, action="store_true",
378*2d543d20SAndroid Build Coastguard Worker                     help=_("Generate HTML man pages structure for selected SELinux man page"))
379*2d543d20SAndroid Build Coastguard Worker    man.add_argument("-r", "--root", dest="root", default="/",
380*2d543d20SAndroid Build Coastguard Worker                     help=_("Alternate root directory, defaults to /"))
381*2d543d20SAndroid Build Coastguard Worker    man.add_argument("--source_files", dest="source_files", default=False, action="store_true",
382*2d543d20SAndroid Build Coastguard Worker                     help=_("With this flag, alternative root path needs to include file context files and policy.xml file"))
383*2d543d20SAndroid Build Coastguard Worker    group = man.add_mutually_exclusive_group(required=True)
384*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-a", "--all", dest="all", default=False,
385*2d543d20SAndroid Build Coastguard Worker                       action="store_true",
386*2d543d20SAndroid Build Coastguard Worker                       help=_("All domains"))
387*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-d", "--domain", nargs="+",
388*2d543d20SAndroid Build Coastguard Worker                       action=CheckDomain,
389*2d543d20SAndroid Build Coastguard Worker                       help=_("Domain name(s) of man pages to be created"))
390*2d543d20SAndroid Build Coastguard Worker    man.set_defaults(func=manpage)
391*2d543d20SAndroid Build Coastguard Worker
392*2d543d20SAndroid Build Coastguard Worker
393*2d543d20SAndroid Build Coastguard Workerdef gen_network_args(parser):
394*2d543d20SAndroid Build Coastguard Worker    net = parser.add_parser("network",
395*2d543d20SAndroid Build Coastguard Worker                            help=_('Query SELinux policy network information'))
396*2d543d20SAndroid Build Coastguard Worker
397*2d543d20SAndroid Build Coastguard Worker    group = net.add_mutually_exclusive_group(required=True)
398*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-l", "--list", dest="list_ports",
399*2d543d20SAndroid Build Coastguard Worker                       action="store_true",
400*2d543d20SAndroid Build Coastguard Worker                       help=_("list all SELinux port types"))
401*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-p", "--port", dest="port", default=[],
402*2d543d20SAndroid Build Coastguard Worker                       action=CheckPort, nargs="+", type=int,
403*2d543d20SAndroid Build Coastguard Worker                       help=_("show SELinux type related to the port"))
404*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-t", "--type", dest="type", default=[],
405*2d543d20SAndroid Build Coastguard Worker                       action=CheckPortType, nargs="+",
406*2d543d20SAndroid Build Coastguard Worker                       help=_("Show ports defined for this SELinux type"))
407*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-d", "--domain", dest="domain", default=[],
408*2d543d20SAndroid Build Coastguard Worker                       action=CheckDomain, nargs="+",
409*2d543d20SAndroid Build Coastguard Worker                       help=_("show ports to which this domain can bind and/or connect"))
410*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-a", "--application", dest="applications", default=[],
411*2d543d20SAndroid Build Coastguard Worker                       nargs="+",
412*2d543d20SAndroid Build Coastguard Worker                       help=_("show ports to which this application can bind and/or connect"))
413*2d543d20SAndroid Build Coastguard Worker    net.set_defaults(func=network)
414*2d543d20SAndroid Build Coastguard Worker
415*2d543d20SAndroid Build Coastguard Worker
416*2d543d20SAndroid Build Coastguard Workerdef communicate(args):
417*2d543d20SAndroid Build Coastguard Worker    from sepolicy.communicate import get_types
418*2d543d20SAndroid Build Coastguard Worker
419*2d543d20SAndroid Build Coastguard Worker    writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
420*2d543d20SAndroid Build Coastguard Worker    readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
421*2d543d20SAndroid Build Coastguard Worker    out = list(set(writable) & set(readable))
422*2d543d20SAndroid Build Coastguard Worker
423*2d543d20SAndroid Build Coastguard Worker    for t in out:
424*2d543d20SAndroid Build Coastguard Worker        print(t)
425*2d543d20SAndroid Build Coastguard Worker
426*2d543d20SAndroid Build Coastguard Worker
427*2d543d20SAndroid Build Coastguard Workerdef gen_communicate_args(parser):
428*2d543d20SAndroid Build Coastguard Worker    comm = parser.add_parser("communicate",
429*2d543d20SAndroid Build Coastguard Worker                             help=_('query SELinux policy to see if domains can communicate with each other'))
430*2d543d20SAndroid Build Coastguard Worker    comm.add_argument("-s", "--source", dest="source",
431*2d543d20SAndroid Build Coastguard Worker                      action=CheckDomain, required=True,
432*2d543d20SAndroid Build Coastguard Worker                      help=_("Source Domain"))
433*2d543d20SAndroid Build Coastguard Worker    comm.add_argument("-t", "--target", dest="target",
434*2d543d20SAndroid Build Coastguard Worker                      action=CheckDomain, required=True,
435*2d543d20SAndroid Build Coastguard Worker                      help=_("Target Domain"))
436*2d543d20SAndroid Build Coastguard Worker    comm.add_argument("-c", "--class", required=False, dest="tclass",
437*2d543d20SAndroid Build Coastguard Worker                      action=CheckClass,
438*2d543d20SAndroid Build Coastguard Worker                      default="file", help="class to use for communications, Default 'file'")
439*2d543d20SAndroid Build Coastguard Worker    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'")
440*2d543d20SAndroid Build Coastguard Worker    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'")
441*2d543d20SAndroid Build Coastguard Worker    comm.set_defaults(func=communicate)
442*2d543d20SAndroid Build Coastguard Worker
443*2d543d20SAndroid Build Coastguard Worker
444*2d543d20SAndroid Build Coastguard Workerdef booleans(args):
445*2d543d20SAndroid Build Coastguard Worker    from sepolicy import boolean_desc
446*2d543d20SAndroid Build Coastguard Worker    if args.all:
447*2d543d20SAndroid Build Coastguard Worker        rc, args.booleans = selinux.security_get_boolean_names()
448*2d543d20SAndroid Build Coastguard Worker    args.booleans.sort()
449*2d543d20SAndroid Build Coastguard Worker
450*2d543d20SAndroid Build Coastguard Worker    for b in args.booleans:
451*2d543d20SAndroid Build Coastguard Worker        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
452*2d543d20SAndroid Build Coastguard Worker
453*2d543d20SAndroid Build Coastguard Worker
454*2d543d20SAndroid Build Coastguard Workerdef gen_booleans_args(parser):
455*2d543d20SAndroid Build Coastguard Worker    bools = parser.add_parser("booleans",
456*2d543d20SAndroid Build Coastguard Worker                              help=_('query SELinux Policy to see description of booleans'))
457*2d543d20SAndroid Build Coastguard Worker    group = bools.add_mutually_exclusive_group(required=True)
458*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-a", "--all", dest="all", default=False,
459*2d543d20SAndroid Build Coastguard Worker                       action="store_true",
460*2d543d20SAndroid Build Coastguard Worker                       help=_("get all booleans descriptions"))
461*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-b", "--boolean", dest="booleans", nargs="+",
462*2d543d20SAndroid Build Coastguard Worker                       action=CheckBoolean, required=False,
463*2d543d20SAndroid Build Coastguard Worker                       help=_("boolean to get description"))
464*2d543d20SAndroid Build Coastguard Worker    bools.set_defaults(func=booleans)
465*2d543d20SAndroid Build Coastguard Worker
466*2d543d20SAndroid Build Coastguard Worker
467*2d543d20SAndroid Build Coastguard Workerdef transition(args):
468*2d543d20SAndroid Build Coastguard Worker    from sepolicy.transition import setrans
469*2d543d20SAndroid Build Coastguard Worker    mytrans = setrans(args.source, args.target)
470*2d543d20SAndroid Build Coastguard Worker    mytrans.output()
471*2d543d20SAndroid Build Coastguard Worker
472*2d543d20SAndroid Build Coastguard Worker
473*2d543d20SAndroid Build Coastguard Workerdef gen_transition_args(parser):
474*2d543d20SAndroid Build Coastguard Worker    trans = parser.add_parser("transition",
475*2d543d20SAndroid Build Coastguard Worker                              help=_('query SELinux Policy to see how a source process domain can transition to the target process domain'))
476*2d543d20SAndroid Build Coastguard Worker    trans.add_argument("-s", "--source", dest="source",
477*2d543d20SAndroid Build Coastguard Worker                       action=CheckDomain, required=True,
478*2d543d20SAndroid Build Coastguard Worker                       help=_("source process domain"))
479*2d543d20SAndroid Build Coastguard Worker    trans.add_argument("-t", "--target", dest="target",
480*2d543d20SAndroid Build Coastguard Worker                       action=CheckDomain,
481*2d543d20SAndroid Build Coastguard Worker                       help=_("target process domain"))
482*2d543d20SAndroid Build Coastguard Worker    trans.set_defaults(func=transition)
483*2d543d20SAndroid Build Coastguard Worker
484*2d543d20SAndroid Build Coastguard Worker
485*2d543d20SAndroid Build Coastguard Workerdef print_interfaces(interfaces, args, append=""):
486*2d543d20SAndroid Build Coastguard Worker    from sepolicy.interface import get_interface_format_text, interface_compile_test
487*2d543d20SAndroid Build Coastguard Worker    for i in interfaces:
488*2d543d20SAndroid Build Coastguard Worker        if args.verbose:
489*2d543d20SAndroid Build Coastguard Worker            try:
490*2d543d20SAndroid Build Coastguard Worker                print(get_interface_format_text(i + append))
491*2d543d20SAndroid Build Coastguard Worker            except KeyError:
492*2d543d20SAndroid Build Coastguard Worker                print(i)
493*2d543d20SAndroid Build Coastguard Worker        if args.compile:
494*2d543d20SAndroid Build Coastguard Worker            try:
495*2d543d20SAndroid Build Coastguard Worker                interface_compile_test(i)
496*2d543d20SAndroid Build Coastguard Worker            except KeyError:
497*2d543d20SAndroid Build Coastguard Worker                print(i)
498*2d543d20SAndroid Build Coastguard Worker        else:
499*2d543d20SAndroid Build Coastguard Worker            print(i)
500*2d543d20SAndroid Build Coastguard Worker
501*2d543d20SAndroid Build Coastguard Worker
502*2d543d20SAndroid Build Coastguard Workerdef interface(args):
503*2d543d20SAndroid Build Coastguard Worker    from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces
504*2d543d20SAndroid Build Coastguard Worker    if args.list_admin:
505*2d543d20SAndroid Build Coastguard Worker        print_interfaces(get_admin(args.file), args, "_admin")
506*2d543d20SAndroid Build Coastguard Worker    if args.list_user:
507*2d543d20SAndroid Build Coastguard Worker        print_interfaces(get_user(args.file), args, "_role")
508*2d543d20SAndroid Build Coastguard Worker    if args.list:
509*2d543d20SAndroid Build Coastguard Worker        print_interfaces(get_all_interfaces(args.file), args)
510*2d543d20SAndroid Build Coastguard Worker    if args.interfaces:
511*2d543d20SAndroid Build Coastguard Worker        print_interfaces(args.interfaces, args)
512*2d543d20SAndroid Build Coastguard Worker
513*2d543d20SAndroid Build Coastguard Worker
514*2d543d20SAndroid Build Coastguard Workerdef generate(args):
515*2d543d20SAndroid Build Coastguard Worker    from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE
516*2d543d20SAndroid Build Coastguard Worker    cmd = None
517*2d543d20SAndroid Build Coastguard Worker# numbers present POLTYPE defined in sepolicy.generate
518*2d543d20SAndroid Build Coastguard Worker    conflict_args = {'TYPES': (NEWTYPE,), 'DOMAIN': (EUSER,), 'ADMIN_DOMAIN': (AUSER, RUSER, EUSER,)}
519*2d543d20SAndroid Build Coastguard Worker    error_text = ""
520*2d543d20SAndroid Build Coastguard Worker
521*2d543d20SAndroid Build Coastguard Worker    if args.policytype is None:
522*2d543d20SAndroid Build Coastguard Worker        generate_usage = generate_custom_usage(usage, usage_dict)
523*2d543d20SAndroid Build Coastguard Worker        for k in usage_dict:
524*2d543d20SAndroid Build Coastguard Worker            error_text += "%s" % (k)
525*2d543d20SAndroid Build Coastguard Worker        print(generate_usage)
526*2d543d20SAndroid Build Coastguard Worker        print(_("sepolicy generate: error: one of the arguments %s is required") % error_text)
527*2d543d20SAndroid Build Coastguard Worker        sys.exit(1)
528*2d543d20SAndroid Build Coastguard Worker
529*2d543d20SAndroid Build Coastguard Worker    if args.policytype in APPLICATIONS:
530*2d543d20SAndroid Build Coastguard Worker        if not args.command:
531*2d543d20SAndroid Build Coastguard Worker            raise ValueError(_("Command required for this type of policy"))
532*2d543d20SAndroid Build Coastguard Worker        cmd = os.path.realpath(args.command)
533*2d543d20SAndroid Build Coastguard Worker        if not args.name:
534*2d543d20SAndroid Build Coastguard Worker            args.name = os.path.basename(cmd).replace("-", "_")
535*2d543d20SAndroid Build Coastguard Worker
536*2d543d20SAndroid Build Coastguard Worker    mypolicy = policy(args.name, args.policytype)
537*2d543d20SAndroid Build Coastguard Worker    if cmd:
538*2d543d20SAndroid Build Coastguard Worker        mypolicy.set_program(cmd)
539*2d543d20SAndroid Build Coastguard Worker
540*2d543d20SAndroid Build Coastguard Worker    if args.types:
541*2d543d20SAndroid Build Coastguard Worker        if args.policytype not in conflict_args['TYPES']:
542*2d543d20SAndroid Build Coastguard Worker            raise ValueError(_("-t option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
543*2d543d20SAndroid Build Coastguard Worker        mypolicy.set_types(args.types)
544*2d543d20SAndroid Build Coastguard Worker
545*2d543d20SAndroid Build Coastguard Worker    if args.domain:
546*2d543d20SAndroid Build Coastguard Worker        if args.policytype not in conflict_args['DOMAIN']:
547*2d543d20SAndroid Build Coastguard Worker            raise ValueError(_("-d option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
548*2d543d20SAndroid Build Coastguard Worker
549*2d543d20SAndroid Build Coastguard Worker    if args.admin_domain:
550*2d543d20SAndroid Build Coastguard Worker        if args.policytype not in conflict_args['ADMIN_DOMAIN']:
551*2d543d20SAndroid Build Coastguard Worker            raise ValueError(_("-a option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype])
552*2d543d20SAndroid Build Coastguard Worker
553*2d543d20SAndroid Build Coastguard Worker    if len(args.writepaths) > 0 and args.policytype == NEWTYPE:
554*2d543d20SAndroid Build Coastguard Worker
555*2d543d20SAndroid Build Coastguard Worker        raise ValueError(_("-w option can not be used with the --newtype option"))
556*2d543d20SAndroid Build Coastguard Worker
557*2d543d20SAndroid Build Coastguard Worker    for p in args.writepaths:
558*2d543d20SAndroid Build Coastguard Worker        if os.path.isdir(p):
559*2d543d20SAndroid Build Coastguard Worker            mypolicy.add_dir(p)
560*2d543d20SAndroid Build Coastguard Worker        else:
561*2d543d20SAndroid Build Coastguard Worker            mypolicy.add_file(p)
562*2d543d20SAndroid Build Coastguard Worker
563*2d543d20SAndroid Build Coastguard Worker    mypolicy.set_transition_users(args.user)
564*2d543d20SAndroid Build Coastguard Worker    mypolicy.set_admin_roles(args.role)
565*2d543d20SAndroid Build Coastguard Worker    mypolicy.set_admin_domains(args.admin_domain)
566*2d543d20SAndroid Build Coastguard Worker    mypolicy.set_existing_domains(args.domain)
567*2d543d20SAndroid Build Coastguard Worker
568*2d543d20SAndroid Build Coastguard Worker    if args.policytype in APPLICATIONS:
569*2d543d20SAndroid Build Coastguard Worker        mypolicy.gen_writeable()
570*2d543d20SAndroid Build Coastguard Worker        mypolicy.gen_symbols()
571*2d543d20SAndroid Build Coastguard Worker    print(mypolicy.generate(args.path))
572*2d543d20SAndroid Build Coastguard Worker
573*2d543d20SAndroid Build Coastguard Worker
574*2d543d20SAndroid Build Coastguard Workerdef gen_interface_args(parser):
575*2d543d20SAndroid Build Coastguard Worker    itf = parser.add_parser("interface",
576*2d543d20SAndroid Build Coastguard Worker                            help=_('List SELinux Policy interfaces'))
577*2d543d20SAndroid Build Coastguard Worker    itf.add_argument("-c", "--compile", dest="compile",
578*2d543d20SAndroid Build Coastguard Worker                     action="store_true", default=False,
579*2d543d20SAndroid Build Coastguard Worker                     help="Run compile test for selected interface")
580*2d543d20SAndroid Build Coastguard Worker    itf.add_argument("-v", "--verbose", dest="verbose",
581*2d543d20SAndroid Build Coastguard Worker                     action="store_true", default=False,
582*2d543d20SAndroid Build Coastguard Worker                     help="Show verbose information")
583*2d543d20SAndroid Build Coastguard Worker    itf.add_argument("-f", "--file", dest="file",
584*2d543d20SAndroid Build Coastguard Worker                     help="Interface file")
585*2d543d20SAndroid Build Coastguard Worker    group = itf.add_mutually_exclusive_group(required=True)
586*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-a", "--list_admin", dest="list_admin", action="store_true", default=False,
587*2d543d20SAndroid Build Coastguard Worker                       help="List all domains with admin interface - DOMAIN_admin()")
588*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-u", "--list_user", dest="list_user", action="store_true",
589*2d543d20SAndroid Build Coastguard Worker                       default=False,
590*2d543d20SAndroid Build Coastguard Worker                       help="List all domains with SELinux user role interface - DOMAIN_role()")
591*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-l", "--list", dest="list", action="store_true",
592*2d543d20SAndroid Build Coastguard Worker                       default=False,
593*2d543d20SAndroid Build Coastguard Worker                       help="List all interfaces")
594*2d543d20SAndroid Build Coastguard Worker    group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces",
595*2d543d20SAndroid Build Coastguard Worker                       action=InterfaceInfo,
596*2d543d20SAndroid Build Coastguard Worker                       help=_("Enter interface names, you wish to query"))
597*2d543d20SAndroid Build Coastguard Worker    itf.set_defaults(func=interface)
598*2d543d20SAndroid Build Coastguard Worker
599*2d543d20SAndroid Build Coastguard Worker
600*2d543d20SAndroid Build Coastguard Workerdef gen_generate_args(parser):
601*2d543d20SAndroid Build Coastguard Worker    from sepolicy.generate import get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE
602*2d543d20SAndroid Build Coastguard Worker
603*2d543d20SAndroid Build Coastguard Worker    generate_usage = generate_custom_usage(usage, usage_dict)
604*2d543d20SAndroid Build Coastguard Worker
605*2d543d20SAndroid Build Coastguard Worker    pol = parser.add_parser("generate", usage=generate_usage,
606*2d543d20SAndroid Build Coastguard Worker                            help=_('Generate SELinux Policy module template'))
607*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-d", "--domain", dest="domain", default=[],
608*2d543d20SAndroid Build Coastguard Worker                     action=CheckDomain, nargs="*",
609*2d543d20SAndroid Build Coastguard Worker                     help=_("Enter domain type which you will be extending"))
610*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-u", "--user", dest="user", default=[],
611*2d543d20SAndroid Build Coastguard Worker                     action=CheckUser,
612*2d543d20SAndroid Build Coastguard Worker                     help=_("Enter SELinux user(s) which will transition to this domain"))
613*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-r", "--role", dest="role", default=[],
614*2d543d20SAndroid Build Coastguard Worker                     action=CheckRole,
615*2d543d20SAndroid Build Coastguard Worker                     help=_("Enter SELinux role(s) to which the administror domain will transition"))
616*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-a", "--admin", dest="admin_domain", default=[],
617*2d543d20SAndroid Build Coastguard Worker                     action=CheckAdmin,
618*2d543d20SAndroid Build Coastguard Worker                     help=_("Enter domain(s) which this confined admin will administrate"))
619*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-n", "--name", dest="name",
620*2d543d20SAndroid Build Coastguard Worker                     default=None,
621*2d543d20SAndroid Build Coastguard Worker                     help=_("name of policy to generate"))
622*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-T", "--test", dest="test", default=False, action="store_true",
623*2d543d20SAndroid Build Coastguard Worker                     help=argparse.SUPPRESS)
624*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-t", "--type", dest="types", default=[], nargs="*",
625*2d543d20SAndroid Build Coastguard Worker                     action=CheckType,
626*2d543d20SAndroid Build Coastguard Worker                     help="Enter type(s) for which you will generate new definition and rule(s)")
627*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-p", "--path", dest="path", default=os.getcwd(),
628*2d543d20SAndroid Build Coastguard Worker                     help=_("path in which the generated policy files will be stored"))
629*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default=[],
630*2d543d20SAndroid Build Coastguard Worker                     help=_("path to which the confined processes will need to write"))
631*2d543d20SAndroid Build Coastguard Worker    cmdtype = pol.add_argument_group(_("Policy types which require a command"))
632*2d543d20SAndroid Build Coastguard Worker    cmdgroup = cmdtype.add_mutually_exclusive_group(required=False)
633*2d543d20SAndroid Build Coastguard Worker    cmdgroup.add_argument("--application", dest="policytype", const=USER,
634*2d543d20SAndroid Build Coastguard Worker                          action="store_const",
635*2d543d20SAndroid Build Coastguard Worker                          help=_("Generate '%s' policy") % poltype[USER])
636*2d543d20SAndroid Build Coastguard Worker    cmdgroup.add_argument("--cgi", dest="policytype", const=CGI,
637*2d543d20SAndroid Build Coastguard Worker                          action="store_const",
638*2d543d20SAndroid Build Coastguard Worker                          help=_("Generate '%s' policy") % poltype[CGI])
639*2d543d20SAndroid Build Coastguard Worker    cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS,
640*2d543d20SAndroid Build Coastguard Worker                          action="store_const",
641*2d543d20SAndroid Build Coastguard Worker                          help=_("Generate '%s' policy") % poltype[DBUS])
642*2d543d20SAndroid Build Coastguard Worker    cmdgroup.add_argument("--inetd", dest="policytype", const=INETD,
643*2d543d20SAndroid Build Coastguard Worker                          action="store_const",
644*2d543d20SAndroid Build Coastguard Worker                          help=_("Generate '%s' policy") % poltype[INETD])
645*2d543d20SAndroid Build Coastguard Worker    cmdgroup.add_argument("--init", dest="policytype", const=DAEMON,
646*2d543d20SAndroid Build Coastguard Worker                          action="store_const", default=DAEMON,
647*2d543d20SAndroid Build Coastguard Worker                          help=_("Generate '%s' policy") % poltype[DAEMON])
648*2d543d20SAndroid Build Coastguard Worker
649*2d543d20SAndroid Build Coastguard Worker    type = pol.add_argument_group("Policy types which do not require a command")
650*2d543d20SAndroid Build Coastguard Worker    group = type.add_mutually_exclusive_group(required=False)
651*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--admin_user", dest="policytype", const=AUSER,
652*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
653*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[AUSER])
654*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--confined_admin", dest="policytype", const=RUSER,
655*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
656*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[RUSER])
657*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--customize", dest="policytype", const=EUSER,
658*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
659*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[EUSER])
660*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--desktop_user", dest="policytype", const=LUSER,
661*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
662*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy ") % poltype[LUSER])
663*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--newtype", dest="policytype", const=NEWTYPE,
664*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
665*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[NEWTYPE])
666*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--sandbox", dest="policytype", const=SANDBOX,
667*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
668*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[SANDBOX])
669*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--term_user", dest="policytype", const=TUSER,
670*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
671*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[TUSER])
672*2d543d20SAndroid Build Coastguard Worker    group.add_argument("--x_user", dest="policytype", const=XUSER,
673*2d543d20SAndroid Build Coastguard Worker                       action="store_const",
674*2d543d20SAndroid Build Coastguard Worker                       help=_("Generate '%s' policy") % poltype[XUSER])
675*2d543d20SAndroid Build Coastguard Worker    pol.add_argument("command", nargs="?", default=None,
676*2d543d20SAndroid Build Coastguard Worker                     help=_("executable to confine"))
677*2d543d20SAndroid Build Coastguard Worker    pol.set_defaults(func=generate)
678*2d543d20SAndroid Build Coastguard Worker
679*2d543d20SAndroid Build Coastguard Workerif __name__ == '__main__':
680*2d543d20SAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(description='SELinux Policy Inspection Tool')
681*2d543d20SAndroid Build Coastguard Worker    subparsers = parser.add_subparsers(help=_("commands"))
682*2d543d20SAndroid Build Coastguard Worker    parser.add_argument("-P", "--policy", dest="policy",
683*2d543d20SAndroid Build Coastguard Worker                        action=LoadPolicy,
684*2d543d20SAndroid Build Coastguard Worker                        default=None, help=_("Alternate SELinux policy, defaults to /sys/fs/selinux/policy"))
685*2d543d20SAndroid Build Coastguard Worker    gen_booleans_args(subparsers)
686*2d543d20SAndroid Build Coastguard Worker    gen_communicate_args(subparsers)
687*2d543d20SAndroid Build Coastguard Worker    gen_generate_args(subparsers)
688*2d543d20SAndroid Build Coastguard Worker    gen_gui_args(subparsers)
689*2d543d20SAndroid Build Coastguard Worker    gen_interface_args(subparsers)
690*2d543d20SAndroid Build Coastguard Worker    gen_manpage_args(subparsers)
691*2d543d20SAndroid Build Coastguard Worker    gen_network_args(subparsers)
692*2d543d20SAndroid Build Coastguard Worker    gen_transition_args(subparsers)
693*2d543d20SAndroid Build Coastguard Worker
694*2d543d20SAndroid Build Coastguard Worker    try:
695*2d543d20SAndroid Build Coastguard Worker        if os.path.basename(sys.argv[0]) == "sepolgen":
696*2d543d20SAndroid Build Coastguard Worker            parser_args = [ "generate" ] + sys.argv[1:]
697*2d543d20SAndroid Build Coastguard Worker        elif len(sys.argv) > 1:
698*2d543d20SAndroid Build Coastguard Worker            parser_args = sys.argv[1:]
699*2d543d20SAndroid Build Coastguard Worker        else:
700*2d543d20SAndroid Build Coastguard Worker            parser_args = ["-h"]
701*2d543d20SAndroid Build Coastguard Worker        args = parser.parse_args(args=parser_args)
702*2d543d20SAndroid Build Coastguard Worker        args.func(args)
703*2d543d20SAndroid Build Coastguard Worker        sys.exit(0)
704*2d543d20SAndroid Build Coastguard Worker    except ValueError as e:
705*2d543d20SAndroid Build Coastguard Worker        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
706*2d543d20SAndroid Build Coastguard Worker        sys.exit(1)
707*2d543d20SAndroid Build Coastguard Worker    except IOError as e:
708*2d543d20SAndroid Build Coastguard Worker        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
709*2d543d20SAndroid Build Coastguard Worker        sys.exit(1)
710*2d543d20SAndroid Build Coastguard Worker    except KeyboardInterrupt:
711*2d543d20SAndroid Build Coastguard Worker        print("Out")
712*2d543d20SAndroid Build Coastguard Worker        sys.exit(0)
713