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