1#!/usr/bin/python -Es 2# 3# Copyright (C) 2007-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 os, sys, stat 25import re 26import sepolicy 27from sepolicy import get_all_types, get_all_attributes, get_all_roles 28import time 29 30from templates import executable 31from templates import boolean 32from templates import etc_rw 33from templates import unit_file 34from templates import var_cache 35from templates import var_spool 36from templates import var_lib 37from templates import var_log 38from templates import var_run 39from templates import tmp 40from templates import rw 41from templates import network 42from templates import script 43from templates import spec 44from templates import user 45import sepolgen.interfaces as interfaces 46import sepolgen.defaults as defaults 47 48## 49## I18N 50## 51PROGNAME="policycoreutils" 52 53import gettext 54gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 55gettext.textdomain(PROGNAME) 56try: 57 gettext.install(PROGNAME, 58 localedir="/usr/share/locale", 59 unicode=False, 60 codeset = 'utf-8') 61except IOError: 62 import __builtin__ 63 __builtin__.__dict__['_'] = unicode 64 65def get_rpm_nvr_from_header(hdr): 66 'Given an RPM header return the package NVR as a string' 67 name = hdr['name'] 68 version = hdr['version'] 69 release = hdr['release'] 70 release_version = version+"-"+release.split(".")[0] 71 os_version = release.split(".")[1] 72 73 return [name,release_version,os_version] 74 75def get_rpm_nvr_list(package): 76 try: 77 import rpm 78 nvr = None 79 ts = rpm.ts() 80 mi = ts.dbMatch(rpm.RPMTAG_NAME, package) 81 for h in mi: 82 nvr = get_rpm_nvr_from_header(h) 83 break 84 except: 85 print("Failed to retrieve rpm info for %s") % package 86 nvr = None 87 88 return nvr 89 90def get_all_ports(): 91 dict = {} 92 for p in sepolicy.info(sepolicy.PORT): 93 if p['type'] == "reserved_port_t" or \ 94 p['type'] == "port_t" or \ 95 p['type'] == "hi_reserved_port_t": 96 continue 97 dict[(p['low'], p['high'], p['protocol'])]=(p['type'], p['range']) 98 return dict 99 100def get_all_users(): 101 users = map(lambda x: x['name'], sepolicy.info(sepolicy.USER)) 102 users.remove("system_u") 103 users.remove("root") 104 users.sort() 105 return users 106 107ALL = 0 108RESERVED = 1 109UNRESERVED = 2 110PORTS = 3 111ADMIN_TRANSITION_INTERFACE = "_admin$" 112USER_TRANSITION_INTERFACE = "_role$" 113 114DAEMON = 0 115DBUS = 1 116INETD = 2 117CGI = 3 118SANDBOX = 4 119USER = 5 120EUSER = 6 121TUSER = 7 122XUSER = 8 123LUSER = 9 124AUSER = 10 125RUSER = 11 126NEWTYPE = 12 127 128poltype={} 129poltype[DAEMON] = _("Standard Init Daemon") 130poltype[DBUS] = _("DBUS System Daemon") 131poltype[INETD] = _("Internet Services Daemon") 132poltype[CGI] = _("Web Application/Script (CGI)") 133poltype[SANDBOX] = _("Sandbox") 134poltype[USER] = _("User Application") 135poltype[EUSER] = _("Existing Domain Type") 136poltype[TUSER] = _("Minimal Terminal Login User Role") 137poltype[XUSER] = _("Minimal X Windows Login User Role") 138poltype[LUSER] = _("Desktop Login User Role") 139poltype[AUSER] = _("Administrator Login User Role") 140poltype[RUSER] = _("Confined Root Administrator Role") 141poltype[NEWTYPE] = _("Module information for a new type") 142 143def get_poltype_desc(): 144 keys = poltype.keys() 145 keys.sort() 146 msg = _("Valid Types:\n") 147 for k in keys: 148 msg += "%2s: %s\n" % (k, poltype[k]) 149 return msg 150 151APPLICATIONS = [ DAEMON, DBUS, INETD, USER, CGI ] 152USERS = [ XUSER, TUSER, LUSER, AUSER, RUSER] 153 154def verify_ports(ports): 155 if ports == "": 156 return [] 157 max_port=2**16 158 try: 159 temp = [] 160 for a in ports.split(","): 161 r = a.split("-") 162 if len(r) > 2: 163 raise ValueError 164 if len(r) == 1: 165 begin = int (r[0]) 166 end = int (r[0]) 167 else: 168 begin = int (r[0]) 169 end = int (r[1]) 170 171 if begin > end: 172 raise ValueError 173 174 for p in range(begin, end + 1): 175 if p < 1 or p > max_port: 176 raise ValueError 177 temp.append(p) 178 return temp 179 except ValueError: 180 raise ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port )) 181 182class policy: 183 184 def __init__(self, name, type): 185 self.rpms = [] 186 self.ports = [] 187 self.all_roles = get_all_roles() 188 self.types = [] 189 190 if type not in poltype: 191 raise ValueError(_("You must enter a valid policy type")) 192 193 if not name: 194 raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type]) 195 try: 196 self.ports = get_all_ports() 197 except ValueError, e: 198 print "Can not get port types, must be root for this information" 199 except RuntimeError, e: 200 print "Can not get port types", e 201 202 self.symbols = {} 203 self.symbols["openlog"] = "set_use_kerberos(True)" 204 self.symbols["openlog"] = "set_use_kerb_rcache(True)" 205 self.symbols["openlog"] = "set_use_syslog(True)" 206 self.symbols["gethostby"] = "set_use_resolve(True)" 207 self.symbols["getaddrinfo"] = "set_use_resolve(True)" 208 self.symbols["getnameinfo"] = "set_use_resolve(True)" 209 self.symbols["krb"] = "set_use_kerberos(True)" 210 self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)" 211 self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)" 212 self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)" 213 self.symbols["__syslog_chk"] = "set_use_syslog(True)" 214 self.symbols["getpwnam"] = "set_use_uid(True)" 215 self.symbols["getpwuid"] = "set_use_uid(True)" 216 self.symbols["dbus_"] = "set_use_dbus(True)" 217 self.symbols["pam_"] = "set_use_pam(True)" 218 self.symbols["pam_"] = "set_use_audit(True)" 219 self.symbols["fork"] = "add_process('fork')" 220 self.symbols["transition"] = "add_process('transition')" 221 self.symbols["sigchld"] = "add_process('sigchld')" 222 self.symbols["sigkill"] = "add_process('sigkill')" 223 self.symbols["sigstop"] = "add_process('sigstop')" 224 self.symbols["signull"] = "add_process('signull')" 225 self.symbols["ptrace"] = "add_process('ptrace')" 226 self.symbols["getsched"] = "add_process('getsched')" 227 self.symbols["setsched"] = "add_process('setsched')" 228 self.symbols["getsession"] = "add_process('getsession')" 229 self.symbols["getpgid"] = "add_process('getpgid')" 230 self.symbols["setpgid"] = "add_process('setpgid')" 231 self.symbols["getcap"] = "add_process('getcap')" 232 self.symbols["setcap"] = "add_process('setcap')" 233 self.symbols["share"] = "add_process('share')" 234 self.symbols["getattr"] = "add_process('getattr')" 235 self.symbols["setexec"] = "add_process('setexec')" 236 self.symbols["setfscreate"] = "add_process('setfscreate')" 237 self.symbols["noatsecure"] = "add_process('noatsecure')" 238 self.symbols["siginh"] = "add_process('siginh')" 239 self.symbols["kill"] = "add_process('signal_perms')" 240 self.symbols["setrlimit"] = "add_process('setrlimit')" 241 self.symbols["rlimitinh"] = "add_process('rlimitinh')" 242 self.symbols["dyntransition"] = "add_process('dyntransition')" 243 self.symbols["setcurrent"] = "add_process('setcurrent')" 244 self.symbols["execmem"] = "add_process('execmem')" 245 self.symbols["execstack"] = "add_process('execstack')" 246 self.symbols["execheap"] = "add_process('execheap')" 247 self.symbols["setkeycreate"] = "add_process('setkeycreate')" 248 self.symbols["setsockcreate"] = "add_process('setsockcreate')" 249 250 self.symbols["chown"] = "add_capability('chown')" 251 self.symbols["dac_override"] = "add_capability('dac_override')" 252 self.symbols["dac_read_search"] = "add_capability('dac_read_search')" 253 self.symbols["fowner"] = "add_capability('fowner')" 254 self.symbols["fsetid"] = "add_capability('fsetid')" 255 self.symbols["setgid"] = "add_capability('setgid')" 256 self.symbols["setegid"] = "add_capability('setgid')" 257 self.symbols["setresgid"] = "add_capability('setgid')" 258 self.symbols["setregid"] = "add_capability('setgid')" 259 self.symbols["setresuid"] = "add_capability('setuid')" 260 self.symbols["setuid"] = "add_capability('setuid')" 261 self.symbols["seteuid"] = "add_capability('setuid')" 262 self.symbols["setreuid"] = "add_capability('setuid')" 263 self.symbols["setresuid"] = "add_capability('setuid')" 264 self.symbols["setpcap"] = "add_capability('setpcap')" 265 self.symbols["linux_immutable"] = "add_capability('linux_immutable')" 266 self.symbols["net_bind_service"] = "add_capability('net_bind_service')" 267 self.symbols["net_broadcast"] = "add_capability('net_broadcast')" 268 self.symbols["net_admin"] = "add_capability('net_admin')" 269 self.symbols["net_raw"] = "add_capability('net_raw')" 270 self.symbols["ipc_lock"] = "add_capability('ipc_lock')" 271 self.symbols["ipc_owner"] = "add_capability('ipc_owner')" 272 self.symbols["sys_module"] = "add_capability('sys_module')" 273 self.symbols["sys_rawio"] = "add_capability('sys_rawio')" 274 self.symbols["chroot"] = "add_capability('sys_chroot')" 275 self.symbols["sys_chroot"] = "add_capability('sys_chroot')" 276 self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')" 277 self.symbols["sys_pacct"] = "add_capability('sys_pacct')" 278 self.symbols["mount"] = "add_capability('sys_admin')" 279 self.symbols["unshare"] = "add_capability('sys_admin')" 280 self.symbols["sys_admin"] = "add_capability('sys_admin')" 281 self.symbols["sys_boot"] = "add_capability('sys_boot')" 282 self.symbols["sys_nice"] = "add_capability('sys_nice')" 283 self.symbols["sys_resource"] = "add_capability('sys_resource')" 284 self.symbols["sys_time"] = "add_capability('sys_time')" 285 self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')" 286 self.symbols["mknod"] = "add_capability('mknod')" 287 self.symbols["lease"] = "add_capability('lease')" 288 self.symbols["audit_write"] = "add_capability('audit_write')" 289 self.symbols["audit_control"] = "add_capability('audit_control')" 290 self.symbols["setfcap"] = "add_capability('setfcap')" 291 292 self.DEFAULT_DIRS = {} 293 self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw]; 294 self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp]; 295 self.DEFAULT_DIRS["rw"] = ["rw", [], rw]; 296 self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file]; 297 self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file]; 298 self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file]; 299 self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache]; 300 self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib]; 301 self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log]; 302 self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run]; 303 self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool]; 304 305 self.DEFAULT_EXT = {} 306 self.DEFAULT_EXT["_tmp_t"] = tmp; 307 self.DEFAULT_EXT["_unit_file_t"] = unit_file; 308 self.DEFAULT_EXT["_var_cache_t"] = var_cache; 309 self.DEFAULT_EXT["_var_lib_t"] = var_lib; 310 self.DEFAULT_EXT["_var_log_t"] = var_log; 311 self.DEFAULT_EXT["_var_run_t"] = var_run; 312 self.DEFAULT_EXT["_var_spool_t"] = var_spool; 313 self.DEFAULT_EXT["_port_t"] = network; 314 315 self.DEFAULT_KEYS=["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system" ] 316 317 self.DEFAULT_TYPES = (\ 318( self.generate_daemon_types, self.generate_daemon_rules), \ 319( self.generate_dbusd_types, self.generate_dbusd_rules), \ 320( self.generate_inetd_types, self.generate_inetd_rules), \ 321( self.generate_cgi_types, self.generate_cgi_rules), \ 322( self.generate_sandbox_types, self.generate_sandbox_rules), \ 323( self.generate_userapp_types, self.generate_userapp_rules), \ 324( self.generate_existing_user_types, self.generate_existing_user_rules), \ 325( self.generate_min_login_user_types, self.generate_login_user_rules), \ 326( self.generate_x_login_user_types, self.generate_x_login_user_rules), \ 327( self.generate_login_user_types, self.generate_login_user_rules), \ 328( self.generate_admin_user_types, self.generate_login_user_rules), \ 329( self.generate_root_user_types, self.generate_root_user_rules), \ 330( self.generate_new_types, self.generate_new_rules)) 331 if not re.match(r"^[a-zA-Z0-9-_]+$", name): 332 raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\"")) 333 334 if type == CGI: 335 self.name = "httpd_%s_script" % name 336 else: 337 self.name = name 338 339 self.file_name = name 340 341 self.capabilities = [] 342 self.processes = [] 343 self.type = type 344 self.initscript = "" 345 self.program = None 346 self.in_tcp = [False, False, False, []] 347 self.in_udp = [False, False, False, []] 348 self.out_tcp = [False, False, False, []] 349 self.out_udp = [False, False, False, []] 350 self.use_resolve = False 351 self.use_tmp = False 352 self.use_uid = False 353 self.use_syslog = False 354 self.use_kerberos = False 355 self.manage_krb5_rcache = False 356 self.use_pam = False 357 self.use_dbus = False 358 self.use_audit = False 359 self.use_etc = self.type not in [ EUSER, NEWTYPE ] 360 self.use_localization = self.type not in [ EUSER, NEWTYPE ] 361 self.use_fd = self.type not in [ EUSER, NEWTYPE ] 362 self.use_terminal = False 363 self.use_mail = False 364 self.booleans = {} 365 self.files = {} 366 self.dirs = {} 367 self.found_tcp_ports=[] 368 self.found_udp_ports=[] 369 self.need_tcp_type=False 370 self.need_udp_type=False 371 self.admin_domains = [] 372 self.existing_domains = [] 373 self.transition_domains = [] 374 self.transition_users = [] 375 self.roles = [] 376 377 def __isnetset(self, l): 378 return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0 379 380 def set_admin_domains(self, admin_domains): 381 self.admin_domains = admin_domains 382 383 def set_existing_domains(self, existing_domains): 384 self.existing_domains = existing_domains 385 386 def set_admin_roles(self, roles): 387 self.roles = roles 388 389 def set_transition_domains(self, transition_domains): 390 self.transition_domains = transition_domains 391 392 def set_transition_users(self, transition_users): 393 self.transition_users = transition_users 394 395 def use_in_udp(self): 396 return self.__isnetset(self.in_udp) 397 398 def use_out_udp(self): 399 return self.__isnetset(self.out_udp) 400 401 def use_udp(self): 402 return self.use_in_udp() or self.use_out_udp() 403 404 def use_in_tcp(self): 405 return self.__isnetset(self.in_tcp) 406 407 def use_out_tcp(self): 408 return self.__isnetset(self.out_tcp) 409 410 def use_tcp(self): 411 return self.use_in_tcp() or self.use_out_tcp() 412 413 def use_network(self): 414 return self.use_tcp() or self.use_udp() 415 416 def find_port(self, port, protocol="tcp"): 417 for begin,end,p in self.ports.keys(): 418 if port >= begin and port <= end and protocol == p: 419 return self.ports[begin, end, protocol] 420 return None 421 422 def set_program(self, program): 423 if self.type not in APPLICATIONS: 424 raise ValueError(_("User Role types can not be assigned executables.")) 425 426 self.program = program 427 428 def set_init_script(self, initscript): 429 if self.type != DAEMON: 430 raise ValueError(_("Only Daemon apps can use an init script..")) 431 432 self.initscript = initscript 433 434 def set_in_tcp(self, all, reserved, unreserved, ports): 435 self.in_tcp = [ all, reserved, unreserved, verify_ports(ports)] 436 437 def set_in_udp(self, all, reserved, unreserved, ports): 438 self.in_udp = [ all, reserved, unreserved, verify_ports(ports)] 439 440 def set_out_tcp(self, all, ports): 441 self.out_tcp = [ all , False, False, verify_ports(ports) ] 442 443 def set_out_udp(self, all, ports): 444 self.out_udp = [ all , False, False, verify_ports(ports) ] 445 446 def set_use_resolve(self, val): 447 if val != True and val != False: 448 raise ValueError(_("use_resolve must be a boolean value ")) 449 450 self.use_resolve = val 451 452 def set_use_syslog(self, val): 453 if val != True and val != False: 454 raise ValueError(_("use_syslog must be a boolean value ")) 455 456 self.use_syslog = val 457 458 def set_use_kerberos(self, val): 459 if val != True and val != False: 460 raise ValueError(_("use_kerberos must be a boolean value ")) 461 462 self.use_kerberos = val 463 464 def set_manage_krb5_rcache(self, val): 465 if val != True and val != False: 466 raise ValueError(_("manage_krb5_rcache must be a boolean value ")) 467 468 self.manage_krb5_rcache = val 469 470 def set_use_pam(self, val): 471 self.use_pam = val == True 472 473 def set_use_dbus(self, val): 474 self.use_dbus = val == True 475 476 def set_use_audit(self, val): 477 self.use_audit = val == True 478 479 def set_use_etc(self, val): 480 self.use_etc = val == True 481 482 def set_use_localization(self, val): 483 self.use_localization = val == True 484 485 def set_use_fd(self, val): 486 self.use_fd = val == True 487 488 def set_use_terminal(self, val): 489 self.use_terminal = val == True 490 491 def set_use_mail(self, val): 492 self.use_mail = val == True 493 494 def set_use_tmp(self, val): 495 if self.type in USERS: 496 raise ValueError(_("USER Types automatically get a tmp type")) 497 498 if val: 499 self.DEFAULT_DIRS["/tmp"][1].append("/tmp"); 500 else: 501 self.DEFAULT_DIRS["/tmp"][1]=[] 502 503 def set_use_uid(self, val): 504 self.use_uid = val == True 505 506 def generate_uid_rules(self): 507 if self.use_uid: 508 return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules) 509 else: 510 return "" 511 512 def generate_syslog_rules(self): 513 if self.use_syslog: 514 return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules) 515 else: 516 return "" 517 518 def generate_resolve_rules(self): 519 if self.use_resolve: 520 return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules) 521 else: 522 return "" 523 524 def generate_kerberos_rules(self): 525 if self.use_kerberos: 526 return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules) 527 else: 528 return "" 529 530 def generate_manage_krb5_rcache_rules(self): 531 if self.manage_krb5_rcache: 532 return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules) 533 else: 534 return "" 535 536 def generate_pam_rules(self): 537 newte ="" 538 if self.use_pam: 539 newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules) 540 return newte 541 542 def generate_audit_rules(self): 543 newte ="" 544 if self.use_audit: 545 newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules) 546 return newte 547 548 def generate_etc_rules(self): 549 newte ="" 550 if self.use_etc: 551 newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules) 552 return newte 553 554 def generate_fd_rules(self): 555 newte ="" 556 if self.use_fd: 557 newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules) 558 return newte 559 560 def generate_localization_rules(self): 561 newte ="" 562 if self.use_localization: 563 newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules) 564 return newte 565 566 def generate_dbus_rules(self): 567 newte ="" 568 if self.type != DBUS and self.use_dbus: 569 newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules) 570 return newte 571 572 def generate_mail_rules(self): 573 newte ="" 574 if self.use_mail: 575 newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules) 576 return newte 577 578 def generate_network_action(self, protocol, action, port_name): 579 line = "" 580 method = "corenet_%s_%s_%s" % (protocol, action, port_name) 581 if method in sepolicy.get_methods(): 582 line = "%s(%s_t)\n" % (method, self.name) 583 else: 584 line = """ 585gen_require(` 586 type %s_t; 587') 588allow %s_t %s_t:%s_socket name_%s; 589""" % (port_name, self.name, port_name, protocol, action) 590 return line 591 592 def generate_network_types(self): 593 for i in self.in_tcp[PORTS]: 594 rec = self.find_port(int(i), "tcp") 595 if rec == None: 596 self.need_tcp_type = True; 597 else: 598 port_name = rec[0][:-2] 599 line = self.generate_network_action("tcp", "bind", port_name) 600# line = "corenet_tcp_bind_%s(%s_t)\n" % (port_name, self.name) 601 if line not in self.found_tcp_ports: 602 self.found_tcp_ports.append(line) 603 604 for i in self.out_tcp[PORTS]: 605 rec = self.find_port(int(i), "tcp") 606 if rec == None: 607 self.need_tcp_type = True; 608 else: 609 port_name = rec[0][:-2] 610 line = self.generate_network_action("tcp", "connect", port_name) 611# line = "corenet_tcp_connect_%s(%s_t)\n" % (port_name, self.name) 612 if line not in self.found_tcp_ports: 613 self.found_tcp_ports.append(line) 614 615 for i in self.in_udp[PORTS]: 616 rec = self.find_port(int(i),"udp") 617 if rec == None: 618 self.need_udp_type = True; 619 else: 620 port_name = rec[0][:-2] 621 line = self.generate_network_action("udp", "bind", port_name) 622# line = "corenet_udp_bind_%s(%s_t)\n" % (port_name, self.name) 623 if line not in self.found_udp_ports: 624 self.found_udp_ports.append(line) 625 626 if self.need_udp_type == True or self.need_tcp_type == True: 627 return re.sub("TEMPLATETYPE", self.name, network.te_types) 628 return "" 629 630 def __find_path(self, file): 631 for d in self.DEFAULT_DIRS: 632 if file.find(d) == 0: 633 self.DEFAULT_DIRS[d][1].append(file) 634 return self.DEFAULT_DIRS[d] 635 self.DEFAULT_DIRS["rw"][1].append(file) 636 return self.DEFAULT_DIRS["rw"] 637 638 def add_capability(self, capability): 639 if capability not in self.capabilities: 640 self.capabilities.append(capability) 641 642 def set_types(self, types): 643 self.types = types 644 645 def add_process(self, process): 646 if process not in self.processes: 647 self.processes.append(process) 648 649 def add_boolean(self, name, description): 650 self.booleans[name] = description 651 652 def add_file(self, file): 653 self.files[file] = self.__find_path(file) 654 655 def add_dir(self, file): 656 self.dirs[file] = self.__find_path(file) 657 658 def generate_capabilities(self): 659 newte = "" 660 self.capabilities.sort() 661 if len(self.capabilities) > 0: 662 newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities)) 663 return newte 664 665 def generate_process(self): 666 newte = "" 667 self.processes.sort() 668 if len(self.processes) > 0: 669 newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes)) 670 return newte 671 672 673 def generate_network_rules(self): 674 newte = "" 675 if self.use_network(): 676 newte = "\n" 677 678 newte += re.sub("TEMPLATETYPE", self.name, network.te_network) 679 680 if self.use_tcp(): 681 newte += "\n" 682 newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp) 683 684 if self.use_in_tcp(): 685 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp) 686 687 if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0: 688 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp) 689 690 if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0: 691 newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp) 692 693 694 if self.in_tcp[ALL]: 695 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp) 696 if self.in_tcp[RESERVED]: 697 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp) 698 if self.in_tcp[UNRESERVED]: 699 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp) 700 701 if self.out_tcp[ALL]: 702 newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp) 703 if self.out_tcp[RESERVED]: 704 newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp) 705 if self.out_tcp[UNRESERVED]: 706 newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp) 707 708 for i in self.found_tcp_ports: 709 newte += i 710 711 if self.use_udp(): 712 newte += "\n" 713 newte += re.sub("TEMPLATETYPE", self.name, network.te_udp) 714 715 if self.need_udp_type: 716 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp) 717 if self.use_in_udp(): 718 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp) 719 if self.in_udp[ALL]: 720 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp) 721 if self.in_udp[RESERVED]: 722 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp) 723 if self.in_udp[UNRESERVED]: 724 newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp) 725 726 for i in self.found_udp_ports: 727 newte += i 728 return newte 729 730 def generate_transition_rules(self): 731 newte = "" 732 for app in self.transition_domains: 733 tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules) 734 newte += re.sub("APPLICATION", app, tmp) 735 736 if self.type == USER: 737 for u in self.transition_users: 738 temp = re.sub("TEMPLATETYPE", self.name, executable.te_run_rules) 739 newte += re.sub("USER", u.split("_u")[0], temp) 740 741 return newte 742 743 def generate_admin_rules(self): 744 newte = "" 745 if self.type == EUSER: 746 for d in self.existing_domains: 747 name = d.split("_t")[0] 748 role = name + "_r" 749 for app in self.admin_domains: 750 tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules) 751 if role not in self.all_roles: 752 tmp = re.sub(role, "system_r", tmp) 753 754 755 newte += re.sub("APPLICATION", app, tmp) 756 757 return newte 758 759 if self.type == RUSER: 760 newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules) 761 762 for app in self.admin_domains: 763 tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules) 764 newte += re.sub("APPLICATION", app, tmp) 765 766 for u in self.transition_users: 767 role = u.split("_u")[0] 768 769 if (role + "_r") in self.all_roles: 770 tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules) 771 newte += re.sub("USER", role, tmp) 772 773 return newte 774 775 def generate_dbus_if(self): 776 newif = "" 777 if self.use_dbus: 778 newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules) 779 return newif 780 781 def generate_sandbox_if(self): 782 newif = "" 783 if self.type != SANDBOX: 784 return newif 785 newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules) 786 return newif 787 788 789 def generate_admin_if(self): 790 newif = "" 791 newtypes = "" 792 if self.initscript != "": 793 newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types) 794 newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin) 795 for d in self.DEFAULT_KEYS: 796 if len(self.DEFAULT_DIRS[d][1]) > 0: 797 newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types) 798 newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules) 799 800 if newif != "": 801 ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin) 802 ret += newtypes 803 804 ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin) 805 ret += newif 806 ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin) 807 return ret 808 809 return "" 810 811 def generate_cgi_types(self): 812 return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types) 813 814 def generate_sandbox_types(self): 815 return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types) 816 817 def generate_userapp_types(self): 818 return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types) 819 820 def generate_inetd_types(self): 821 return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types) 822 823 def generate_dbusd_types(self): 824 return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types) 825 826 def generate_min_login_user_types(self): 827 return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types) 828 829 def generate_login_user_types(self): 830 return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types) 831 832 def generate_admin_user_types(self): 833 return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types) 834 835 def generate_existing_user_types(self): 836 if len(self.existing_domains) == 0: 837 raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type]) 838 newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types) 839 newte += """gen_require(`""" 840 841 for d in self.existing_domains: 842 newte += """ 843 type %s;""" % d 844 role = d.split("_t")[0] + "_r" 845 if role in self.all_roles: 846 newte += """ 847 role %s;""" % role 848 newte += """ 849') 850""" 851 return newte; 852 853 def generate_x_login_user_types(self): 854 return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types) 855 856 def generate_root_user_types(self): 857 return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types) 858 859 def generate_new_types(self): 860 newte = "" 861 if len(self.types) == 0: 862 raise ValueError(_("Type field required")) 863 864 for t in self.types: 865 for i in self.DEFAULT_EXT: 866 if t.endswith(i): 867 print t, t[:-len(i)] 868 newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types) 869 break 870 871 if NEWTYPE and newte == "": 872 default_ext = [] 873 for i in self.DEFAULT_EXT: 874 default_ext.append(i) 875 raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext)) 876 877 return newte 878 879 def generate_new_rules(self): 880 return "" 881 882 def generate_daemon_types(self): 883 newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types) 884 if self.initscript != "": 885 newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types) 886 return newte 887 888 def generate_tmp_types(self): 889 if self.use_tmp: 890 return re.sub("TEMPLATETYPE", self.name, tmp.te_types) 891 else: 892 return "" 893 894 def generate_booleans(self): 895 newte = "" 896 for b in self.booleans: 897 tmp = re.sub("BOOLEAN", b, boolean.te_boolean) 898 newte += re.sub("DESCRIPTION", self.booleans[b], tmp) 899 return newte 900 901 def generate_boolean_rules(self): 902 newte = "" 903 for b in self.booleans: 904 newte += re.sub("BOOLEAN", b, boolean.te_rules) 905 return newte 906 907 def generate_sandbox_te(self): 908 return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types) 909 910 def generate_cgi_te(self): 911 return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types) 912 913 def generate_daemon_rules(self): 914 newif = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules) 915 916 return newif 917 918 def generate_new_type_if(self): 919 newif = "" 920 for t in self.types: 921 for i in self.DEFAULT_EXT: 922 if t.endswith(i): 923 reqtype = t[:-len(i)] + "_t" 924 newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules) 925 break 926 return newif 927 928 def generate_login_user_rules(self): 929 return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules) 930 931 def generate_existing_user_rules(self): 932 nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules) 933 return nerules 934 935 def generate_x_login_user_rules(self): 936 return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules) 937 938 def generate_root_user_rules(self): 939 newte =re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules) 940 return newte 941 942 def generate_userapp_rules(self): 943 return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules) 944 945 def generate_inetd_rules(self): 946 return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules) 947 948 def generate_dbusd_rules(self): 949 return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules) 950 951 def generate_tmp_rules(self): 952 if self.use_tmp: 953 return re.sub("TEMPLATETYPE", self.name, tmp.te_rules) 954 else: 955 return "" 956 957 def generate_cgi_rules(self): 958 newte = "" 959 newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules) 960 return newte 961 962 def generate_sandbox_rules(self): 963 newte = "" 964 newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules) 965 return newte 966 967 def generate_user_if(self): 968 newif ="" 969 if self.use_terminal or self.type == USER: 970 newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules) 971 972 if self.type in ( TUSER, XUSER, AUSER, LUSER): 973 newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules) 974 return newif 975 976 def generate_if(self): 977 newif = "" 978 newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules) 979 if self.program: 980 newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules) 981 if self.initscript != "": 982 newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules) 983 984 for d in self.DEFAULT_KEYS: 985 if len(self.DEFAULT_DIRS[d][1]) > 0: 986 newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules) 987 for i in self.DEFAULT_DIRS[d][1]: 988 if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]): 989 newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules) 990 break 991 newif += self.generate_user_if() 992 newif += self.generate_dbus_if() 993 newif += self.generate_admin_if() 994 newif += self.generate_sandbox_if() 995 newif += self.generate_new_type_if() 996 newif += self.generate_new_rules() 997 998 return newif 999 1000 def generate_default_types(self): 1001 return self.DEFAULT_TYPES[self.type][0]() 1002 1003 def generate_default_rules(self): 1004 if self.DEFAULT_TYPES[self.type][1]: 1005 return self.DEFAULT_TYPES[self.type][1]() 1006 return "" 1007 1008 def generate_roles_rules(self): 1009 newte = "" 1010 if self.type in ( TUSER, XUSER, AUSER, LUSER ): 1011 roles = "" 1012 if len(self.roles) > 0: 1013 newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules) 1014 newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules) 1015 for role in self.roles: 1016 tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules) 1017 newte += re.sub("ROLE", role, tmp) 1018 return newte 1019 1020 def generate_te(self): 1021 newte = self.generate_default_types() 1022 for d in self.DEFAULT_KEYS: 1023 if len(self.DEFAULT_DIRS[d][1]) > 0: 1024 # CGI scripts already have a rw_t 1025 if self.type != CGI or d != "rw": 1026 newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types) 1027 1028 if self.type != EUSER: 1029 newte +=""" 1030######################################## 1031# 1032# %s local policy 1033# 1034""" % self.name 1035 newte += self.generate_capabilities() 1036 newte += self.generate_process() 1037 newte += self.generate_network_types() 1038 newte += self.generate_tmp_types() 1039 newte += self.generate_booleans() 1040 newte += self.generate_default_rules() 1041 newte += self.generate_boolean_rules() 1042 1043 for d in self.DEFAULT_KEYS: 1044 if len(self.DEFAULT_DIRS[d][1]) > 0: 1045 if self.type == EUSER: 1046 newte_tmp = "" 1047 for domain in self.existing_domains: 1048 newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2]+"_t", self.DEFAULT_DIRS[d][2].te_rules) 1049 newte += re.sub("TEMPLATETYPE_rw_t", self.name+"_rw_t", newte_tmp) 1050 else: 1051 newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules) 1052 for i in self.DEFAULT_DIRS[d][1]: 1053 if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]): 1054 if self.type == EUSER: 1055 for domain in self.existing_domains: 1056 newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules) 1057 1058 else: 1059 newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules) 1060 break 1061 1062 newte += self.generate_tmp_rules() 1063 newte += self.generate_network_rules() 1064 newte += self.generate_fd_rules() 1065 newte += self.generate_etc_rules() 1066 newte += self.generate_pam_rules() 1067 newte += self.generate_uid_rules() 1068 newte += self.generate_audit_rules() 1069 newte += self.generate_syslog_rules() 1070 newte += self.generate_localization_rules() 1071 newte += self.generate_resolve_rules() 1072 newte += self.generate_roles_rules() 1073 newte += self.generate_mail_rules() 1074 newte += self.generate_transition_rules() 1075 newte += self.generate_admin_rules() 1076 newte += self.generate_dbus_rules() 1077 newte += self.generate_kerberos_rules() 1078 newte += self.generate_manage_krb5_rcache_rules() 1079 1080 return newte 1081 1082 def generate_fc(self): 1083 newfc = "" 1084 fclist = [] 1085 for i in self.files.keys(): 1086 if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]): 1087 t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file) 1088 else: 1089 t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file) 1090 t2 = re.sub("FILENAME", i, t1) 1091 fclist.append(re.sub("FILETYPE", self.files[i][0], t2)) 1092 1093 for i in self.dirs.keys(): 1094 t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir) 1095 t2 = re.sub("FILENAME", i, t1) 1096 fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2)) 1097 1098 if self.type in USERS + [ SANDBOX ]: 1099 if len(fclist) == 0: 1100 return executable.fc_user 1101 1102 if self.type not in USERS + [ SANDBOX, EUSER, NEWTYPE ] and not self.program: 1103 raise ValueError(_("You must enter the executable path for your confined process")) 1104 1105 if self.program: 1106 t1 = re.sub("EXECUTABLE", self.program, executable.fc_program) 1107 fclist.append(re.sub("TEMPLATETYPE", self.name, t1)) 1108 1109 if self.initscript != "": 1110 t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript) 1111 fclist.append(re.sub("TEMPLATETYPE", self.name, t1)) 1112 1113 fclist.sort() 1114 newfc="\n".join(fclist) 1115 return newfc 1116 1117 def generate_user_sh(self): 1118 newsh = "" 1119 if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER): 1120 return newsh 1121 1122 roles = "" 1123 for role in self.roles: 1124 roles += " %s_r" % role 1125 if roles != "": 1126 roles += " system_r" 1127 tmp = re.sub("TEMPLATETYPE", self.name, script.users) 1128 newsh += re.sub("ROLES", roles, tmp) 1129 1130 if self.type == RUSER or self.type == AUSER: 1131 for u in self.transition_users: 1132 tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans) 1133 newsh += re.sub("USER", u, tmp) 1134 1135 if self.type == LUSER: 1136 newsh += re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context) 1137 else: 1138 newsh += re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context) 1139 1140 1141 return newsh 1142 1143 def generate_sh(self): 1144 temp = re.sub("TEMPLATETYPE", self.file_name, script.compile) 1145 temp = re.sub("DOMAINTYPE", self.name, temp) 1146 if self.type == EUSER: 1147 newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp) 1148 else: 1149 newsh = re.sub("TEMPLATEFILE", self.file_name, temp) 1150 newsh += re.sub("DOMAINTYPE", self.name, script.manpage) 1151 1152 if self.program: 1153 newsh += re.sub("FILENAME", self.program, script.restorecon) 1154 if self.initscript != "": 1155 newsh += re.sub("FILENAME", self.initscript, script.restorecon) 1156 1157 for i in self.files.keys(): 1158 newsh += re.sub("FILENAME", i, script.restorecon) 1159 1160 for i in self.dirs.keys(): 1161 newsh += re.sub("FILENAME", i, script.restorecon) 1162 1163 for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]: 1164 if self.find_port(i,"tcp") == None: 1165 t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports) 1166 newsh += re.sub("TEMPLATETYPE", self.name, t1) 1167 1168 for i in self.in_udp[PORTS]: 1169 if self.find_port(i,"udp") == None: 1170 t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports) 1171 newsh += re.sub("TEMPLATETYPE", self.name, t1) 1172 1173 newsh += self.generate_user_sh() 1174 newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm) 1175 1176 return newsh 1177 1178 def generate_spec(self): 1179 newspec = "" 1180 1181 selinux_policyver = get_rpm_nvr_list("selinux-policy")[1] 1182 POLICYCOREUTILSVER = get_rpm_nvr_list("checkpolicy")[1] 1183 1184 newspec += spec.header_comment_section 1185 if self.type in APPLICATIONS: 1186 newspec += spec.define_relabel_files_begin 1187 if self.program: 1188 newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end) 1189 if self.initscript != "": 1190 newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end) 1191 for i in self.files.keys(): 1192 newspec += re.sub("FILENAME", i, spec.define_relabel_files_end) 1193 for i in self.dirs.keys(): 1194 newspec += re.sub("FILENAME", i, spec.define_relabel_files_end) 1195 1196 newspec += re.sub("VERSION", selinux_policyver, spec.base_section) 1197 newspec = re.sub("MODULENAME", self.file_name, newspec) 1198 newspec = re.sub("DOMAINNAME", self.name, newspec) 1199 if len(self.rpms) > 0: 1200 newspec += "Requires(post): %s\n" % ", ".join(self.rpms) 1201 newspec += re.sub("MODULENAME", self.file_name, spec.mid_section) 1202 newspec = re.sub("DOMAINNAME", self.name, newspec) 1203 newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec) 1204 1205 if self.type not in APPLICATIONS: 1206 newspec = re.sub("%relabel_files", "", newspec) 1207 1208 # Remove man pages from EUSER spec file 1209 if self.type == EUSER: 1210 newspec = re.sub(".*%s_selinux.8.*" % self.name,"", newspec) 1211 # Remove user context file from non users spec file 1212 if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER): 1213 newspec = re.sub(".*%s_u.*" % self.name,"", newspec) 1214 return newspec 1215 1216 def write_spec(self, out_dir): 1217 specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name) 1218 fd = open(specfile, "w") 1219 fd.write(self.generate_spec()) 1220 fd.close() 1221 1222 return specfile 1223 1224 def write_te(self, out_dir): 1225 tefile = "%s/%s.te" % (out_dir, self.file_name) 1226 fd = open(tefile, "w") 1227 fd.write(self.generate_te()) 1228 fd.close() 1229 return tefile 1230 1231 def write_sh(self, out_dir): 1232 shfile = "%s/%s.sh" % (out_dir, self.file_name) 1233 fd = open(shfile, "w") 1234 fd.write(self.generate_sh()) 1235 fd.close() 1236 os.chmod(shfile, 0750) 1237 return shfile 1238 1239 def write_if(self, out_dir): 1240 iffile = "%s/%s.if" % (out_dir, self.file_name) 1241 fd = open(iffile, "w") 1242 fd.write(self.generate_if()) 1243 fd.close() 1244 return iffile 1245 1246 def write_fc(self,out_dir): 1247 fcfile = "%s/%s.fc" % (out_dir, self.file_name) 1248 fd = open(fcfile, "w") 1249 fd.write(self.generate_fc()) 1250 fd.close() 1251 return fcfile 1252 1253 def __extract_rpms(self): 1254 import yum 1255 yb = yum.YumBase() 1256 yb.setCacheDir() 1257 1258 for pkg in yb.rpmdb.searchProvides(self.program): 1259 self.rpms.append(pkg.name) 1260 for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist: 1261 for b in self.DEFAULT_DIRS: 1262 if b == "/etc": 1263 continue 1264 if fname.startswith(b): 1265 if os.path.isfile(fname): 1266 self.add_file(fname) 1267 else: 1268 self.add_dir(fname) 1269 1270 for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]): 1271 for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist: 1272 for b in self.DEFAULT_DIRS: 1273 if b == "/etc": 1274 continue 1275 if fname.startswith(b): 1276 if os.path.isfile(fname): 1277 self.add_file(fname) 1278 else: 1279 self.add_dir(fname) 1280 1281 # some packages have own systemd subpackage 1282 # tor-systemd for example 1283 binary_name = self.program.split("/")[-1] 1284 for bpkg in yb.rpmdb.searchNames([ "%s-systemd" % binary_name ]): 1285 for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist: 1286 for b in self.DEFAULT_DIRS: 1287 if b == "/etc": 1288 continue 1289 if fname.startswith(b): 1290 if os.path.isfile(fname): 1291 self.add_file(fname) 1292 else: 1293 self.add_dir(fname) 1294 1295 def gen_writeable(self): 1296 try: 1297 self.__extract_rpms() 1298 except ImportError: 1299 pass 1300 1301 if os.path.isfile("/var/run/%s.pid" % self.name): 1302 self.add_file("/var/run/%s.pid" % self.name) 1303 1304 if os.path.isdir("/var/run/%s" % self.name): 1305 self.add_dir("/var/run/%s" % self.name) 1306 1307 if os.path.isdir("/var/log/%s" % self.name): 1308 self.add_dir("/var/log/%s" % self.name) 1309 1310 if os.path.isfile("/var/log/%s.log" % self.name): 1311 self.add_file("/var/log/%s.log" % self.name) 1312 1313 if os.path.isdir("/var/lib/%s" % self.name): 1314 self.add_dir("/var/lib/%s" % self.name) 1315 1316 if os.path.isfile("/etc/rc.d/init.d/%s" % self.name): 1317 self.set_init_script("/etc/rc\.d/init\.d/%s" % self.name) 1318 1319 # we don't want to have subdir in the .fc policy file 1320 # if we already specify labeling for parent dir 1321 temp_basepath = [] 1322 for p in self.DEFAULT_DIRS.keys(): 1323 temp_dirs = [] 1324 try: 1325 temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/" 1326 except IndexError: 1327 continue 1328 1329 for i in self.DEFAULT_DIRS[p][1]: 1330 if i.startswith(temp_basepath): 1331 temp_dirs.append(i) 1332 else: 1333 continue 1334 1335 if len(temp_dirs) is not 0: 1336 for i in temp_dirs: 1337 if i in self.dirs.keys(): 1338 del(self.dirs[i]) 1339 elif i in self.files.keys(): 1340 del(self.files[i]) 1341 else: 1342 continue 1343 1344 self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs)) 1345 1346 def gen_symbols(self): 1347 if self.type not in APPLICATIONS: 1348 return 1349 if not os.path.exists(self.program): 1350 sys.stderr.write(""" 1351*************************************** 1352Warning %s does not exist 1353*************************************** 1354 1355""" % self.program) 1356 return 1357 fd = os.popen("nm -D %s | grep U" % self.program) 1358 for s in fd.read().split(): 1359 for b in self.symbols: 1360 if s.startswith(b): 1361 exec "self.%s" % self.symbols[b] 1362 fd.close() 1363 1364 def generate(self, out_dir = os.getcwd() ): 1365 out = "Created the following files:\n" 1366 out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file")) 1367 out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file")) 1368 out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file")) 1369 if self.type != NEWTYPE: 1370 out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file")) 1371 out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script")) 1372 return out 1373