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" 36 37import gettext 38gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 39gettext.textdomain(PROGNAME) 40try: 41 gettext.install(PROGNAME, 42 localedir="/usr/share/locale", 43 unicode=False, 44 codeset='utf-8') 45except IOError: 46 import __builtin__ 47 __builtin__.__dict__['_'] = unicode 48 49 50def get_interfaces_from_xml(path): 51 """ Get all interfaces from given xml file""" 52 interfaces_list = [] 53 idict = get_interface_dict(path) 54 for k in idict.keys(): 55 interfaces_list.append(k) 56 return interfaces_list 57 58 59def get_all_interfaces(path=""): 60 from sepolicy import get_methods 61 all_interfaces = [] 62 if not path: 63 all_interfaces = get_methods() 64 else: 65 xml_path = get_xml_file(path) 66 all_interfaces = get_interfaces_from_xml(xml_path) 67 68 return all_interfaces 69 70 71def get_admin(path=""): 72 """ Get all domains with an admin interface from installed policy.""" 73 """ If xml_path is specified, func returns an admin interface from specified xml file""" 74 admin_list = [] 75 if path: 76 try: 77 xml_path = get_xml_file(path) 78 idict = get_interface_dict(xml_path) 79 for k in idict.keys(): 80 if k.endswith("_admin"): 81 admin_list.append(k) 82 except IOError, e: 83 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) 84 sys.exit(1) 85 else: 86 for i in sepolicy.get_methods(): 87 if i.endswith("_admin"): 88 admin_list.append(i.split("_admin")[0]) 89 90 return admin_list 91 92 93def get_user(path=""): 94 """ Get all domains with SELinux user role interface""" 95 """ If xml_path is specified, func returns an user role interface from specified xml file""" 96 trans_list = [] 97 if path: 98 try: 99 xml_path = get_xml_file(path) 100 idict = get_interface_dict(xml_path) 101 for k in idict.keys(): 102 if k.endswith("_role"): 103 if (("%s_exec_t" % k[:-5]) in sepolicy.get_all_types()): 104 trans_list.append(k) 105 except IOError, e: 106 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) 107 sys.exit(1) 108 else: 109 for i in sepolicy.get_methods(): 110 m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i) 111 if len(m) > 0: 112 if "%s_exec_t" % m[0] in sepolicy.get_all_types(): 113 trans_list.append(m[0]) 114 115 return trans_list 116 117interface_dict = None 118 119 120def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"): 121 global interface_dict 122 import os 123 import xml.etree.ElementTree 124 if interface_dict: 125 return interface_dict 126 127 interface_dict = {} 128 param_list = [] 129 130 xml_path = """<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 131<policy> 132<layer name="admin"> 133""" 134 xml_path += path 135 xml_path += """ 136</layer> 137</policy> 138""" 139 140 try: 141 if os.path.isfile(path): 142 tree = xml.etree.ElementTree.parse(path) 143 else: 144 tree = xml.etree.ElementTree.fromstring(xml_path) 145 for l in tree.findall("layer"): 146 for m in l.findall("module"): 147 for i in m.getiterator('interface'): 148 for e in i.findall("param"): 149 param_list.append(e.get('name')) 150 interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "interface"] 151 param_list = [] 152 for i in m.getiterator('template'): 153 for e in i.findall("param"): 154 param_list.append(e.get('name')) 155 interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "template"] 156 param_list = [] 157 except IOError, e: 158 pass 159 return interface_dict 160 161 162def get_interface_format_text(interface, path="/usr/share/selinux/devel/policy.xml"): 163 idict = get_interface_dict(path) 164 interface_text = "%s(%s) %s" % (interface, ", ".join(idict[interface][0]), " ".join(idict[interface][1].split("\n"))) 165 166 return interface_text 167 168 169def get_interface_compile_format_text(interfaces_dict, interface): 170 from templates import test_module 171 param_tmp = [] 172 for i in interfaces_dict[interface][0]: 173 param_tmp.append(test_module.dict_values[i]) 174 interface_text = "%s(%s)\n" % (interface, ", ".join(param_tmp)) 175 176 return interface_text 177 178 179def generate_compile_te(interface, idict, name="compiletest"): 180 from templates import test_module 181 te = "" 182 te += re.sub("TEMPLATETYPE", name, test_module.te_test_module) 183 te += get_interface_compile_format_text(idict, interface) 184 185 return te 186 187 188def get_xml_file(if_file): 189 """ Returns xml format of interfaces for given .if policy file""" 190 import os 191 import commands 192 basedir = os.path.dirname(if_file) + "/" 193 filename = os.path.basename(if_file).split(".")[0] 194 rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename) 195 if rc != 0: 196 sys.stderr.write("\n Could not proceed selected interface file.\n") 197 sys.stderr.write("\n%s" % output) 198 sys.exit(1) 199 else: 200 return output 201 202 203def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"): 204 exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"] 205 exclude_interface_type = ["template"] 206 207 import commands 208 import os 209 policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"} 210 idict = get_interface_dict(path) 211 212 if not (interface.split("_")[0] in exclude_interfaces or idict[interface][2] in exclude_interface_type): 213 print(_("Compiling %s interface" % interface)) 214 try: 215 fd = open(policy_files['te'], "w") 216 fd.write(generate_compile_te(interface, idict)) 217 fd.close() 218 rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp']) 219 if rc != 0: 220 sys.stderr.write(output) 221 sys.stderr.write(_("\nCompile test for %s failed.\n") % interface) 222 223 except EnvironmentError, e: 224 sys.stderr.write(_("\nCompile test for %s has not run. %s\n") % (interface, e)) 225 for v in policy_files.values(): 226 if os.path.exists(v): 227 os.remove(v) 228 229 else: 230 sys.stderr.write(_("\nCompiling of %s interface is not supported." % interface)) 231