• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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