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