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