• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python -Es
2#
3# Copyright (C) 2012 Red Hat
4# see file 'COPYING' for use and warranty information
5#
6# policygentool is a tool for the initial generation of SELinux policy
7#
8#    This program is free software; you can redistribute it and/or
9#    modify it under the terms of the GNU General Public License as
10#    published by the Free Software Foundation; either version 2 of
11#    the License, or (at your option) any later version.
12#
13#    This program is distributed in the hope that it will be useful,
14#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16#    GNU General Public License for more details.
17#
18#    You should have received a copy of the GNU General Public License
19#    along with this program; if not, write to the Free Software
20#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21#                                        02111-1307  USA
22#
23#
24import re
25import sys
26import sepolicy
27ADMIN_TRANSITION_INTERFACE = "_admin$"
28USER_TRANSITION_INTERFACE = "_role$"
29
30__all__ = ['get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user', 'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test']
31
32##
33## I18N
34##
35PROGNAME = "policycoreutils"
36try:
37    import gettext
38    kwargs = {}
39    if sys.version_info < (3,):
40        kwargs['unicode'] = True
41    gettext.install(PROGNAME,
42                    localedir="/usr/share/locale",
43                    codeset='utf-8',
44                    **kwargs)
45except:
46    try:
47        import builtins
48        builtins.__dict__['_'] = str
49    except ImportError:
50        import __builtin__
51        __builtin__.__dict__['_'] = unicode
52
53
54def get_interfaces_from_xml(path):
55    """ Get all interfaces from given xml file"""
56    interfaces_list = []
57    idict = get_interface_dict(path)
58    for k in idict.keys():
59        interfaces_list.append(k)
60    return interfaces_list
61
62
63def get_all_interfaces(path=""):
64    from sepolicy import get_methods
65    all_interfaces = []
66    if not path:
67        all_interfaces = get_methods()
68    else:
69        xml_path = get_xml_file(path)
70        all_interfaces = get_interfaces_from_xml(xml_path)
71
72    return all_interfaces
73
74
75def get_admin(path=""):
76    """ Get all domains with an admin interface from installed policy."""
77    """ If xml_path is specified, func returns an admin interface from specified xml file"""
78    admin_list = []
79    if path:
80        try:
81            xml_path = get_xml_file(path)
82            idict = get_interface_dict(xml_path)
83            for k in idict.keys():
84                if k.endswith("_admin"):
85                    admin_list.append(k)
86        except IOError as e:
87            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
88            sys.exit(1)
89    else:
90        for i in sepolicy.get_methods():
91            if i.endswith("_admin"):
92                admin_list.append(i.split("_admin")[0])
93
94    return admin_list
95
96
97def get_user(path=""):
98    """ Get all domains with SELinux user role interface"""
99    """ If xml_path is specified, func returns an user role interface from specified xml file"""
100    trans_list = []
101    if path:
102        try:
103            xml_path = get_xml_file(path)
104            idict = get_interface_dict(xml_path)
105            for k in idict.keys():
106                if k.endswith("_role"):
107                    if (("%s_exec_t" % k[:-5]) in sepolicy.get_all_types()):
108                        trans_list.append(k)
109        except IOError as e:
110            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
111            sys.exit(1)
112    else:
113        for i in sepolicy.get_methods():
114            m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i)
115            if len(m) > 0:
116                if "%s_exec_t" % m[0] in sepolicy.get_all_types():
117                    trans_list.append(m[0])
118
119    return trans_list
120
121interface_dict = None
122
123
124def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
125    global interface_dict
126    import os
127    import xml.etree.ElementTree
128    if interface_dict:
129        return interface_dict
130
131    interface_dict = {}
132    param_list = []
133
134    xml_path = """<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
135<policy>
136<layer name="admin">
137"""
138    xml_path += path
139    xml_path += """
140</layer>
141</policy>
142"""
143
144    try:
145        if os.path.isfile(path):
146            tree = xml.etree.ElementTree.parse(path)
147        else:
148            tree = xml.etree.ElementTree.fromstring(xml_path)
149        for l in tree.findall("layer"):
150            for m in l.findall("module"):
151                for i in m.getiterator('interface'):
152                    for e in i.findall("param"):
153                        param_list.append(e.get('name'))
154                    interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "interface"]
155                    param_list = []
156                for i in m.getiterator('template'):
157                    for e in i.findall("param"):
158                        param_list.append(e.get('name'))
159                    interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "template"]
160                    param_list = []
161    except IOError:
162        pass
163    return interface_dict
164
165
166def get_interface_format_text(interface, path="/usr/share/selinux/devel/policy.xml"):
167    idict = get_interface_dict(path)
168    interface_text = "%s(%s) %s" % (interface, ", ".join(idict[interface][0]), " ".join(idict[interface][1].split("\n")))
169
170    return interface_text
171
172
173def get_interface_compile_format_text(interfaces_dict, interface):
174    from templates import test_module
175    param_tmp = []
176    for i in interfaces_dict[interface][0]:
177        param_tmp.append(test_module.dict_values[i])
178        interface_text = "%s(%s)\n" % (interface, ", ".join(param_tmp))
179
180    return interface_text
181
182
183def generate_compile_te(interface, idict, name="compiletest"):
184    from templates import test_module
185    te = ""
186    te += re.sub("TEMPLATETYPE", name, test_module.te_test_module)
187    te += get_interface_compile_format_text(idict, interface)
188
189    return te
190
191
192def get_xml_file(if_file):
193    """ Returns xml format of interfaces for given .if policy file"""
194    import os
195    try:
196            from commands import getstatusoutput
197    except ImportError:
198            from subprocess import getstatusoutput
199    basedir = os.path.dirname(if_file) + "/"
200    filename = os.path.basename(if_file).split(".")[0]
201    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
202    if rc != 0:
203        sys.stderr.write("\n Could not proceed selected interface file.\n")
204        sys.stderr.write("\n%s" % output)
205        sys.exit(1)
206    else:
207        return output
208
209
210def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"):
211    exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
212    exclude_interface_type = ["template"]
213
214    try:
215            from commands import getstatusoutput
216    except ImportError:
217            from subprocess import getstatusoutput
218    import os
219    policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
220    idict = get_interface_dict(path)
221
222    if not (interface.split("_")[0] in exclude_interfaces or idict[interface][2] in exclude_interface_type):
223        print(_("Compiling %s interface" % interface))
224        try:
225            fd = open(policy_files['te'], "w")
226            fd.write(generate_compile_te(interface, idict))
227            fd.close()
228            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
229            if rc != 0:
230                sys.stderr.write(output)
231                sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
232
233        except EnvironmentError as e:
234            sys.stderr.write(_("\nCompile test for %s has not run. %s\n") % (interface, e))
235        for v in policy_files.values():
236            if os.path.exists(v):
237                os.remove(v)
238
239    else:
240        sys.stderr.write(_("\nCompiling of %s interface is not supported." % interface))
241