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