Home | History | Annotate | Download | only in gui
      1 #!/usr/bin/python -Es
      2 #
      3 # polgengui.py - GUI for SELinux Config tool in system-config-selinux
      4 #
      5 # Dan Walsh <dwalsh (at] redhat.com>
      6 #
      7 # Copyright (C) 2007-2013 Red Hat
      8 #
      9 # This program is free software; you can redistribute it and/or modify
     10 # it under the terms of the GNU General Public License as published by
     11 # the Free Software Foundation; either version 2 of the License, or
     12 # (at your option) any later version.
     13 #
     14 # This program is distributed in the hope that it will be useful,
     15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 # GNU General Public License for more details.
     18 #
     19 # You should have received a copy of the GNU General Public License
     20 # along with this program; if not, write to the Free Software
     21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     22 #
     23 import signal
     24 import string
     25 import gi
     26 gi.require_version('Gtk', '3.0')
     27 from gi.repository import Gtk
     28 import os
     29 from gi.repository import GObject
     30 import sys
     31 try:
     32     import sepolicy
     33 except ValueError as e:
     34     sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
     35     sys.exit(1)
     36 
     37 import sepolicy.interface
     38 try:
     39     from subprocess import getstatusoutput
     40 except ImportError:
     41     from commands import getstatusoutput
     42 
     43 
     44 import re
     45 
     46 
     47 def get_all_modules():
     48     try:
     49         all_modules = []
     50         rc, output = getstatusoutput("semodule -l 2>/dev/null")
     51         if rc == 0:
     52             l = output.split("\n")
     53             for i in l:
     54                 all_modules.append(i.split()[0])
     55     except:
     56         pass
     57 
     58     return all_modules
     59 
     60 
     61 ##
     62 ## I18N
     63 ##
     64 PROGNAME = "policycoreutils"
     65 try:
     66     import gettext
     67     kwargs = {}
     68     if sys.version_info < (3,):
     69         kwargs['unicode'] = True
     70     gettext.install(PROGNAME,
     71                     localedir="/usr/share/locale",
     72                     codeset='utf-8',
     73                     **kwargs)
     74 except:
     75     try:
     76         import builtins
     77         builtins.__dict__['_'] = str
     78     except ImportError:
     79         import __builtin__
     80         __builtin__.__dict__['_'] = unicode
     81 
     82 version = "1.0"
     83 
     84 sys.path.append('/usr/share/system-config-selinux')
     85 sys.path.append('.')
     86 
     87 # From John Hunter http://www.daa.com.au/pipermail/pygtk/2003-February/004454.html
     88 
     89 
     90 def foreach(model, path, iter, selected):
     91     selected.append(model.get_value(iter, 0))
     92 
     93 ##
     94 ## Pull in the Glade file
     95 ##
     96 xml = Gtk.Builder()
     97 xml.set_translation_domain(PROGNAME)
     98 if os.access("polgen.glade", os.F_OK):
     99     xml.add_from_file("polgen.glade")
    100 else:
    101     xml.add_from_file("/usr/share/system-config-selinux/polgen.glade")
    102 
    103 FILE = 1
    104 DIR = 2
    105 
    106 
    107 class childWindow:
    108     START_PAGE = 0
    109     SELECT_TYPE_PAGE = 0
    110     APP_PAGE = 1
    111     EXISTING_USER_PAGE = 2
    112     TRANSITION_PAGE = 3
    113     USER_TRANSITION_PAGE = 4
    114     ADMIN_PAGE = 5
    115     ROLE_PAGE = 6
    116     IN_NET_PAGE = 7
    117     OUT_NET_PAGE = 8
    118     COMMON_APPS_PAGE = 9
    119     FILES_PAGE = 10
    120     BOOLEAN_PAGE = 11
    121     SELECT_DIR_PAGE = 12
    122     FINISH_PAGE = 12
    123 
    124     def __init__(self):
    125         self.xml = xml
    126         self.notebook = xml.get_widget("notebook")
    127         self.label_dict = {}
    128         self.tooltip_dict = {}
    129         label = xml.get_widget("select_label")
    130         self.label_dict[label] = label.get_text()
    131 
    132         label = xml.get_widget("select_user_roles_label")
    133         self.label_dict[label] = label.get_text()
    134 
    135         label = xml.get_widget("select_dir_label")
    136         self.label_dict[label] = label.get_text()
    137 
    138         label = xml.get_widget("select_domain_admin_label")
    139         self.label_dict[label] = label.get_text()
    140 
    141         label = xml.get_widget("select_in_label")
    142         self.label_dict[label] = label.get_text()
    143 
    144         label = xml.get_widget("select_out_label")
    145         self.label_dict[label] = label.get_text()
    146 
    147         label = xml.get_widget("select_common_label")
    148         self.label_dict[label] = label.get_text()
    149 
    150         label = xml.get_widget("select_manages_label")
    151         self.label_dict[label] = label.get_text()
    152 
    153         label = xml.get_widget("select_booleans_label")
    154         self.label_dict[label] = label.get_text()
    155 
    156         label = xml.get_widget("existing_user_treeview")
    157         self.tooltip_dict[label] = label.get_tooltip_text()
    158 
    159         label = xml.get_widget("transition_treeview")
    160         self.tooltip_dict[label] = label.get_tooltip_text()
    161 
    162         label = xml.get_widget("in_tcp_all_checkbutton")
    163         self.tooltip_dict[label] = label.get_tooltip_text()
    164 
    165         label = xml.get_widget("in_tcp_reserved_checkbutton")
    166         self.tooltip_dict[label] = label.get_tooltip_text()
    167 
    168         label = xml.get_widget("in_tcp_unreserved_checkbutton")
    169         self.tooltip_dict[label] = label.get_tooltip_text()
    170 
    171         label = xml.get_widget("in_tcp_entry")
    172         self.tooltip_dict[label] = label.get_tooltip_text()
    173 
    174         label = xml.get_widget("in_udp_all_checkbutton")
    175         self.tooltip_dict[label] = label.get_tooltip_text()
    176 
    177         label = xml.get_widget("in_udp_reserved_checkbutton")
    178         self.tooltip_dict[label] = label.get_tooltip_text()
    179 
    180         label = xml.get_widget("in_udp_unreserved_checkbutton")
    181         self.tooltip_dict[label] = label.get_tooltip_text()
    182 
    183         label = xml.get_widget("in_udp_entry")
    184         self.tooltip_dict[label] = label.get_tooltip_text()
    185 
    186         label = xml.get_widget("out_tcp_entry")
    187         self.tooltip_dict[label] = label.get_tooltip_text()
    188 
    189         label = xml.get_widget("out_udp_entry")
    190         self.tooltip_dict[label] = label.get_tooltip_text()
    191 
    192         label = xml.get_widget("out_tcp_all_checkbutton")
    193         self.tooltip_dict[label] = label.get_tooltip_text()
    194 
    195         label = xml.get_widget("out_udp_all_checkbutton")
    196         self.tooltip_dict[label] = label.get_tooltip_text()
    197 
    198         label = xml.get_widget("boolean_treeview")
    199         self.tooltip_dict[label] = label.get_tooltip_text()
    200 
    201         label = xml.get_widget("write_treeview")
    202         self.tooltip_dict[label] = label.get_tooltip_text()
    203 
    204         try:
    205             self.all_types = sepolicy.generate.get_all_types()
    206             self.all_modules = get_all_modules()
    207             self.all_roles = sepolicy.generate.get_all_roles()
    208             self.all_users = sepolicy.generate.get_all_users()
    209         except RuntimeError as e:
    210             self.all_types = []
    211             self.all_modules = []
    212             self.all_roles = []
    213             self.all_users = []
    214             self.error(str(e))
    215 
    216         self.name = ""
    217         xml.signal_connect("on_delete_clicked", self.delete)
    218         xml.signal_connect("on_delete_boolean_clicked", self.delete_boolean)
    219         xml.signal_connect("on_exec_select_clicked", self.exec_select)
    220         xml.signal_connect("on_init_script_select_clicked", self.init_script_select)
    221         xml.signal_connect("on_add_clicked", self.add)
    222         xml.signal_connect("on_add_boolean_clicked", self.add_boolean)
    223         xml.signal_connect("on_add_dir_clicked", self.add_dir)
    224         xml.signal_connect("on_about_clicked", self.on_about_clicked)
    225         xml.get_widget("cancel_button").connect("clicked", self.quit)
    226         self.forward_button = xml.get_widget("forward_button")
    227         self.forward_button.connect("clicked", self.forward)
    228         self.back_button = xml.get_widget("back_button")
    229         self.back_button.connect("clicked", self.back)
    230 
    231         self.boolean_dialog = xml.get_widget("boolean_dialog")
    232         self.boolean_name_entry = xml.get_widget("boolean_name_entry")
    233         self.boolean_description_entry = xml.get_widget("boolean_description_entry")
    234 
    235         self.pages = {}
    236         for i in sepolicy.generate.USERS:
    237             self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    238         self.pages[sepolicy.generate.RUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    239         self.pages[sepolicy.generate.LUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    240         self.pages[sepolicy.generate.SANDBOX] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    241         self.pages[sepolicy.generate.EUSER] = [self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    242 
    243         for i in sepolicy.generate.APPLICATIONS:
    244             self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    245         self.pages[sepolicy.generate.USER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
    246 
    247         self.current_page = 0
    248         self.back_button.set_sensitive(0)
    249 
    250         self.network_buttons = {}
    251 
    252         self.in_tcp_all_checkbutton = xml.get_widget("in_tcp_all_checkbutton")
    253         self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
    254         self.in_tcp_unreserved_checkbutton = xml.get_widget("in_tcp_unreserved_checkbutton")
    255         self.in_tcp_entry = self.xml.get_widget("in_tcp_entry")
    256         self.network_buttons[self.in_tcp_all_checkbutton] = [self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry]
    257 
    258         self.out_tcp_all_checkbutton = xml.get_widget("out_tcp_all_checkbutton")
    259         self.out_tcp_reserved_checkbutton = xml.get_widget("out_tcp_reserved_checkbutton")
    260         self.out_tcp_unreserved_checkbutton = xml.get_widget("out_tcp_unreserved_checkbutton")
    261         self.out_tcp_entry = self.xml.get_widget("out_tcp_entry")
    262 
    263         self.network_buttons[self.out_tcp_all_checkbutton] = [self.out_tcp_entry]
    264 
    265         self.in_udp_all_checkbutton = xml.get_widget("in_udp_all_checkbutton")
    266         self.in_udp_reserved_checkbutton = xml.get_widget("in_udp_reserved_checkbutton")
    267         self.in_udp_unreserved_checkbutton = xml.get_widget("in_udp_unreserved_checkbutton")
    268         self.in_udp_entry = self.xml.get_widget("in_udp_entry")
    269 
    270         self.network_buttons[self.in_udp_all_checkbutton] = [self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry]
    271 
    272         self.out_udp_all_checkbutton = xml.get_widget("out_udp_all_checkbutton")
    273         self.out_udp_entry = self.xml.get_widget("out_udp_entry")
    274         self.network_buttons[self.out_udp_all_checkbutton] = [self.out_udp_entry]
    275 
    276         for b in self.network_buttons.keys():
    277             b.connect("clicked", self.network_all_clicked)
    278 
    279         self.boolean_treeview = self.xml.get_widget("boolean_treeview")
    280         self.boolean_store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
    281         self.boolean_treeview.set_model(self.boolean_store)
    282         self.boolean_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    283         col = Gtk.TreeViewColumn(_("Name"), Gtk.CellRendererText(), text=0)
    284         self.boolean_treeview.append_column(col)
    285         col = Gtk.TreeViewColumn(_("Description"), Gtk.CellRendererText(), text=1)
    286         self.boolean_treeview.append_column(col)
    287 
    288         self.role_treeview = self.xml.get_widget("role_treeview")
    289         self.role_store = Gtk.ListStore(GObject.TYPE_STRING)
    290         self.role_treeview.set_model(self.role_store)
    291         self.role_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    292         self.role_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    293         col = Gtk.TreeViewColumn(_("Role"), Gtk.CellRendererText(), text=0)
    294         self.role_treeview.append_column(col)
    295 
    296         self.existing_user_treeview = self.xml.get_widget("existing_user_treeview")
    297         self.existing_user_store = Gtk.ListStore(GObject.TYPE_STRING)
    298         self.existing_user_treeview.set_model(self.existing_user_store)
    299         self.existing_user_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    300         col = Gtk.TreeViewColumn(_("Existing_User"), Gtk.CellRendererText(), text=0)
    301         self.existing_user_treeview.append_column(col)
    302 
    303         for i in self.all_roles:
    304             iter = self.role_store.append()
    305             self.role_store.set_value(iter, 0, i[:-2])
    306 
    307         self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
    308 
    309         self.transition_treeview = self.xml.get_widget("transition_treeview")
    310         self.transition_store = Gtk.ListStore(GObject.TYPE_STRING)
    311         self.transition_treeview.set_model(self.transition_store)
    312         self.transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    313         self.transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    314         col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
    315         self.transition_treeview.append_column(col)
    316 
    317         self.user_transition_treeview = self.xml.get_widget("user_transition_treeview")
    318         self.user_transition_store = Gtk.ListStore(GObject.TYPE_STRING)
    319         self.user_transition_treeview.set_model(self.user_transition_store)
    320         self.user_transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    321         self.user_transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    322         col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
    323         self.user_transition_treeview.append_column(col)
    324 
    325         for i in self.all_users:
    326             iter = self.user_transition_store.append()
    327             self.user_transition_store.set_value(iter, 0, i[:-2])
    328             iter = self.existing_user_store.append()
    329             self.existing_user_store.set_value(iter, 0, i[:-2])
    330 
    331         self.admin_treeview = self.xml.get_widget("admin_treeview")
    332         self.admin_store = Gtk.ListStore(GObject.TYPE_STRING)
    333         self.admin_treeview.set_model(self.admin_store)
    334         self.admin_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    335         self.admin_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
    336         col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0)
    337         self.admin_treeview.append_column(col)
    338 
    339         try:
    340             for u in sepolicy.interface.get_user():
    341                 iter = self.transition_store.append()
    342                 self.transition_store.set_value(iter, 0, u)
    343 
    344             for a in sepolicy.interface.get_admin():
    345                 iter = self.admin_store.append()
    346                 self.admin_store.set_value(iter, 0, a)
    347         except ValueError as e:
    348             self.error(e.message)
    349 
    350     def confine_application(self):
    351         return self.get_type() in sepolicy.generate.APPLICATIONS
    352 
    353     def forward(self, arg):
    354         type = self.get_type()
    355         if self.current_page == self.START_PAGE:
    356             self.back_button.set_sensitive(1)
    357 
    358         if self.pages[type][self.current_page] == self.SELECT_TYPE_PAGE:
    359             if self.on_select_type_page_next():
    360                 return
    361 
    362         if self.pages[type][self.current_page] == self.IN_NET_PAGE:
    363             if self.on_in_net_page_next():
    364                 return
    365 
    366         if self.pages[type][self.current_page] == self.OUT_NET_PAGE:
    367             if self.on_out_net_page_next():
    368                 return
    369 
    370         if self.pages[type][self.current_page] == self.APP_PAGE:
    371             if self.on_name_page_next():
    372                 return
    373 
    374         if self.pages[type][self.current_page] == self.EXISTING_USER_PAGE:
    375             if self.on_existing_user_page_next():
    376                 return
    377 
    378         if self.pages[type][self.current_page] == self.SELECT_DIR_PAGE:
    379             outputdir = self.output_entry.get_text()
    380             if not os.path.isdir(outputdir):
    381                 self.error(_("%s must be a directory") % outputdir)
    382                 return False
    383 
    384         if self.pages[type][self.current_page] == self.FINISH_PAGE:
    385             self.generate_policy()
    386             self.xml.get_widget("cancel_button").set_label(Gtk.STOCK_CLOSE)
    387         else:
    388             self.current_page = self.current_page + 1
    389             self.notebook.set_current_page(self.pages[type][self.current_page])
    390             if self.pages[type][self.current_page] == self.FINISH_PAGE:
    391                 self.forward_button.set_label(Gtk.STOCK_APPLY)
    392 
    393     def back(self, arg):
    394         type = self.get_type()
    395         if self.pages[type][self.current_page] == self.FINISH_PAGE:
    396             self.forward_button.set_label(Gtk.STOCK_GO_FORWARD)
    397 
    398         self.current_page = self.current_page - 1
    399         self.notebook.set_current_page(self.pages[type][self.current_page])
    400         if self.pages[type][self.current_page] == self.START_PAGE:
    401             self.back_button.set_sensitive(0)
    402 
    403     def network_all_clicked(self, button):
    404         active = button.get_active()
    405         for b in self.network_buttons[button]:
    406             b.set_sensitive(not active)
    407 
    408     def verify(self, message, title=""):
    409         dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
    410                                 Gtk.ButtonsType.YES_NO,
    411                                 message)
    412         dlg.set_title(title)
    413         dlg.set_position(Gtk.WindowPosition.MOUSE)
    414         dlg.show_all()
    415         rc = dlg.run()
    416         dlg.destroy()
    417         return rc
    418 
    419     def info(self, message):
    420         dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
    421                                 Gtk.ButtonsType.OK,
    422                                 message)
    423         dlg.set_position(Gtk.WindowPosition.MOUSE)
    424         dlg.show_all()
    425         dlg.run()
    426         dlg.destroy()
    427 
    428     def error(self, message):
    429         dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,
    430                                 Gtk.ButtonsType.CLOSE,
    431                                 message)
    432         dlg.set_position(Gtk.WindowPosition.MOUSE)
    433         dlg.show_all()
    434         dlg.run()
    435         dlg.destroy()
    436 
    437     def get_name(self):
    438         if self.existing_user_radiobutton.get_active():
    439             store, iter = self.existing_user_treeview.get_selection().get_selected()
    440             if iter == None:
    441                 raise ValueError(_("You must select a user"))
    442             return store.get_value(iter, 0)
    443         else:
    444             return self.name_entry.get_text()
    445 
    446     def get_type(self):
    447         if self.sandbox_radiobutton.get_active():
    448             return sepolicy.generate.SANDBOX
    449         if self.cgi_radiobutton.get_active():
    450             return sepolicy.generate.CGI
    451         if self.user_radiobutton.get_active():
    452             return sepolicy.generate.USER
    453         if self.init_radiobutton.get_active():
    454             return sepolicy.generate.DAEMON
    455         if self.dbus_radiobutton.get_active():
    456             return sepolicy.generate.DBUS
    457         if self.inetd_radiobutton.get_active():
    458             return sepolicy.generate.INETD
    459         if self.login_user_radiobutton.get_active():
    460             return sepolicy.generate.LUSER
    461         if self.admin_user_radiobutton.get_active():
    462             return sepolicy.generate.AUSER
    463         if self.xwindows_user_radiobutton.get_active():
    464             return sepolicy.generate.XUSER
    465         if self.terminal_user_radiobutton.get_active():
    466             return sepolicy.generate.TUSER
    467         if self.root_user_radiobutton.get_active():
    468             return sepolicy.generate.RUSER
    469         if self.existing_user_radiobutton.get_active():
    470             return sepolicy.generate.EUSER
    471 
    472     def generate_policy(self, *args):
    473         outputdir = self.output_entry.get_text()
    474         try:
    475             my_policy = sepolicy.generate.policy(self.get_name(), self.get_type())
    476 
    477             iter = self.boolean_store.get_iter_first()
    478             while(iter):
    479                 my_policy.add_boolean(self.boolean_store.get_value(iter, 0), self.boolean_store.get_value(iter, 1))
    480                 iter = self.boolean_store.iter_next(iter)
    481 
    482             if self.get_type() in sepolicy.generate.APPLICATIONS:
    483                 my_policy.set_program(self.exec_entry.get_text())
    484                 my_policy.gen_symbols()
    485 
    486                 my_policy.set_use_syslog(self.syslog_checkbutton.get_active() == 1)
    487                 my_policy.set_use_tmp(self.tmp_checkbutton.get_active() == 1)
    488                 my_policy.set_use_uid(self.uid_checkbutton.get_active() == 1)
    489                 my_policy.set_use_pam(self.pam_checkbutton.get_active() == 1)
    490 
    491                 my_policy.set_use_dbus(self.dbus_checkbutton.get_active() == 1)
    492                 my_policy.set_use_audit(self.audit_checkbutton.get_active() == 1)
    493                 my_policy.set_use_terminal(self.terminal_checkbutton.get_active() == 1)
    494                 my_policy.set_use_mail(self.mail_checkbutton.get_active() == 1)
    495                 if self.get_type() is sepolicy.generate.DAEMON:
    496                     my_policy.set_init_script(self.init_script_entry.get_text())
    497                 if self.get_type() == sepolicy.generate.USER:
    498                     selected = []
    499                     self.user_transition_treeview.get_selection().selected_foreach(foreach, selected)
    500                     my_policy.set_transition_users(selected)
    501             else:
    502                 if self.get_type() == sepolicy.generate.RUSER:
    503                     selected = []
    504                     self.admin_treeview.get_selection().selected_foreach(foreach, selected)
    505                     my_policy.set_admin_domains(selected)
    506                     selected = []
    507                     self.user_transition_treeview.get_selection().selected_foreach(foreach, selected)
    508                     my_policy.set_transition_users(selected)
    509                 else:
    510                     selected = []
    511                     self.transition_treeview.get_selection().selected_foreach(foreach, selected)
    512                     my_policy.set_transition_domains(selected)
    513 
    514                     selected = []
    515                     self.role_treeview.get_selection().selected_foreach(foreach, selected)
    516                     my_policy.set_admin_roles(selected)
    517 
    518             my_policy.set_in_tcp(self.in_tcp_all_checkbutton.get_active(), self.in_tcp_reserved_checkbutton.get_active(), self.in_tcp_unreserved_checkbutton.get_active(), self.in_tcp_entry.get_text())
    519             my_policy.set_in_udp(self.in_udp_all_checkbutton.get_active(), self.in_udp_reserved_checkbutton.get_active(), self.in_udp_unreserved_checkbutton.get_active(), self.in_udp_entry.get_text())
    520             my_policy.set_out_tcp(self.out_tcp_all_checkbutton.get_active(), self.out_tcp_entry.get_text())
    521             my_policy.set_out_udp(self.out_udp_all_checkbutton.get_active(), self.out_udp_entry.get_text())
    522 
    523             iter = self.store.get_iter_first()
    524             while(iter):
    525                 if self.store.get_value(iter, 1) == FILE:
    526                     my_policy.add_file(self.store.get_value(iter, 0))
    527                 else:
    528                     my_policy.add_dir(self.store.get_value(iter, 0))
    529                 iter = self.store.iter_next(iter)
    530 
    531             self.info(my_policy.generate(outputdir))
    532             return False
    533         except ValueError as e:
    534             self.error(e.message)
    535 
    536     def delete(self, args):
    537         store, iter = self.view.get_selection().get_selected()
    538         if iter != None:
    539             store.remove(iter)
    540             self.view.get_selection().select_path((0,))
    541 
    542     def delete_boolean(self, args):
    543         store, iter = self.boolean_treeview.get_selection().get_selected()
    544         if iter != None:
    545             store.remove(iter)
    546             self.boolean_treeview.get_selection().select_path((0,))
    547 
    548     def add_boolean(self, type):
    549         self.boolean_name_entry.set_text("")
    550         self.boolean_description_entry.set_text("")
    551         rc = self.boolean_dialog.run()
    552         self.boolean_dialog.hide()
    553         if rc == Gtk.ResponseType.CANCEL:
    554             return
    555         iter = self.boolean_store.append()
    556         self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text())
    557         self.boolean_store.set_value(iter, 1, self.boolean_description_entry.get_text())
    558 
    559     def __add(self, type):
    560         rc = self.file_dialog.run()
    561         self.file_dialog.hide()
    562         if rc == Gtk.ResponseType.CANCEL:
    563             return
    564         for i in self.file_dialog.get_filenames():
    565             iter = self.store.append()
    566             self.store.set_value(iter, 0, i)
    567             self.store.set_value(iter, 1, type)
    568 
    569     def exec_select(self, args):
    570         self.file_dialog.set_select_multiple(0)
    571         self.file_dialog.set_title(_("Select executable file to be confined."))
    572         self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
    573         self.file_dialog.set_current_folder("/usr/sbin")
    574         rc = self.file_dialog.run()
    575         self.file_dialog.hide()
    576         if rc == Gtk.ResponseType.CANCEL:
    577             return
    578         self.exec_entry.set_text(self.file_dialog.get_filename())
    579 
    580     def init_script_select(self, args):
    581         self.file_dialog.set_select_multiple(0)
    582         self.file_dialog.set_title(_("Select init script file to be confined."))
    583         self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
    584         self.file_dialog.set_current_folder("/etc/rc.d/init.d")
    585         rc = self.file_dialog.run()
    586         self.file_dialog.hide()
    587         if rc == Gtk.ResponseType.CANCEL:
    588             return
    589         self.init_script_entry.set_text(self.file_dialog.get_filename())
    590 
    591     def add(self, args):
    592         self.file_dialog.set_title(_("Select file(s) that confined application creates or writes"))
    593         self.file_dialog.set_current_folder("/")
    594         self.file_dialog.set_action(Gtk.FileChooserAction.OPEN)
    595         self.file_dialog.set_select_multiple(1)
    596         self.__add(FILE)
    597 
    598     def add_dir(self, args):
    599         self.file_dialog.set_title(_("Select directory(s) that the confined application owns and writes into"))
    600         self.file_dialog.set_current_folder("/")
    601         self.file_dialog.set_select_multiple(1)
    602         self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
    603         self.__add(DIR)
    604 
    605     def on_about_clicked(self, args):
    606         dlg = xml.get_widget("about_dialog")
    607         dlg.run()
    608         dlg.hide()
    609 
    610     def quit(self, args):
    611         Gtk.main_quit()
    612 
    613     def setupScreen(self):
    614         # Bring in widgets from glade file.
    615         self.mainWindow = self.xml.get_widget("main_window")
    616         self.druid = self.xml.get_widget("druid")
    617         self.type = 0
    618         self.name_entry = self.xml.get_widget("name_entry")
    619         self.name_entry.connect("insert_text", self.on_name_entry_changed)
    620         self.name_entry.connect("focus_out_event", self.on_focus_out_event)
    621         self.exec_entry = self.xml.get_widget("exec_entry")
    622         self.exec_button = self.xml.get_widget("exec_button")
    623         self.init_script_entry = self.xml.get_widget("init_script_entry")
    624         self.init_script_button = self.xml.get_widget("init_script_button")
    625         self.output_entry = self.xml.get_widget("output_entry")
    626         self.output_entry.set_text(os.getcwd())
    627         self.xml.get_widget("output_button").connect("clicked", self.output_button_clicked)
    628 
    629         self.xwindows_user_radiobutton = self.xml.get_widget("xwindows_user_radiobutton")
    630         self.terminal_user_radiobutton = self.xml.get_widget("terminal_user_radiobutton")
    631         self.root_user_radiobutton = self.xml.get_widget("root_user_radiobutton")
    632         self.login_user_radiobutton = self.xml.get_widget("login_user_radiobutton")
    633         self.admin_user_radiobutton = self.xml.get_widget("admin_user_radiobutton")
    634         self.existing_user_radiobutton = self.xml.get_widget("existing_user_radiobutton")
    635 
    636         self.user_radiobutton = self.xml.get_widget("user_radiobutton")
    637         self.init_radiobutton = self.xml.get_widget("init_radiobutton")
    638         self.inetd_radiobutton = self.xml.get_widget("inetd_radiobutton")
    639         self.dbus_radiobutton = self.xml.get_widget("dbus_radiobutton")
    640         self.cgi_radiobutton = self.xml.get_widget("cgi_radiobutton")
    641         self.sandbox_radiobutton = self.xml.get_widget("sandbox_radiobutton")
    642         self.tmp_checkbutton = self.xml.get_widget("tmp_checkbutton")
    643         self.uid_checkbutton = self.xml.get_widget("uid_checkbutton")
    644         self.pam_checkbutton = self.xml.get_widget("pam_checkbutton")
    645         self.dbus_checkbutton = self.xml.get_widget("dbus_checkbutton")
    646         self.audit_checkbutton = self.xml.get_widget("audit_checkbutton")
    647         self.terminal_checkbutton = self.xml.get_widget("terminal_checkbutton")
    648         self.mail_checkbutton = self.xml.get_widget("mail_checkbutton")
    649         self.syslog_checkbutton = self.xml.get_widget("syslog_checkbutton")
    650         self.view = self.xml.get_widget("write_treeview")
    651         self.file_dialog = self.xml.get_widget("filechooserdialog")
    652 
    653         self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
    654         self.view.set_model(self.store)
    655         col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0)
    656         col.set_resizable(True)
    657         self.view.append_column(col)
    658         self.view.get_selection().select_path((0,))
    659 
    660     def output_button_clicked(self, *args):
    661         self.file_dialog.set_title(_("Select directory to generate policy files in"))
    662         self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
    663         self.file_dialog.set_select_multiple(0)
    664         rc = self.file_dialog.run()
    665         self.file_dialog.hide()
    666         if rc == Gtk.ResponseType.CANCEL:
    667             return
    668         self.output_entry.set_text(self.file_dialog.get_filename())
    669 
    670     def on_name_entry_changed(self, entry, text, size, position):
    671         if text.find(" ") >= 0:
    672             entry.emit_stop_by_name("insert_text")
    673 
    674     def on_focus_out_event(self, entry, third):
    675         name = entry.get_text()
    676         if self.name != name:
    677             if name in self.all_types:
    678                 if self.verify(_("Type %s_t already defined in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO:
    679                     entry.set_text("")
    680                     return False
    681             if name in self.all_modules:
    682                 if self.verify(_("Module %s already loaded in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO:
    683                     entry.set_text("")
    684                     return False
    685 
    686             file = "/etc/rc.d/init.d/" + name
    687             if os.path.isfile(file) and self.init_script_entry.get_text() == "":
    688                 self.init_script_entry.set_text(file)
    689 
    690             file = "/usr/sbin/" + name
    691             if os.path.isfile(file) and self.exec_entry.get_text() == "":
    692                 self.exec_entry.set_text(file)
    693 
    694         self.name = name
    695         return False
    696 
    697     def on_in_net_page_next(self, *args):
    698         try:
    699             generate.verify_ports(self.in_tcp_entry.get_text())
    700             generate.verify_ports(self.in_udp_entry.get_text())
    701         except ValueError as e:
    702             self.error(e.message)
    703             return True
    704 
    705     def on_out_net_page_next(self, *args):
    706         try:
    707             generate.verify_ports(self.out_tcp_entry.get_text())
    708             generate.verify_ports(self.out_udp_entry.get_text())
    709         except ValueError as e:
    710             self.error(e.message)
    711             return True
    712 
    713     def on_select_type_page_next(self, *args):
    714         self.exec_entry.set_sensitive(self.confine_application())
    715         self.exec_button.set_sensitive(self.confine_application())
    716         self.init_script_entry.set_sensitive(self.init_radiobutton.get_active())
    717         self.init_script_button.set_sensitive(self.init_radiobutton.get_active())
    718 
    719     def on_existing_user_page_next(self, *args):
    720         store, iter = self.view.get_selection().get_selected()
    721         if iter != None:
    722             self.error(_("You must select a user"))
    723             return True
    724 
    725     def on_name_page_next(self, *args):
    726         name = self.name_entry.get_text()
    727         if not name.isalnum():
    728             self.error(_("You must add a name made up of letters and numbers and containing no spaces."))
    729             return True
    730 
    731         for i in self.label_dict:
    732             text = '<b>%s</b>' % (self.label_dict[i] % ("'" + name + "'"))
    733             i.set_markup(text)
    734 
    735         for i in self.tooltip_dict:
    736             text = self.tooltip_dict[i] % ("'" + name + "'")
    737             i.set_tooltip_text(text)
    738 
    739         if self.confine_application():
    740             exe = self.exec_entry.get_text()
    741             if exe == "":
    742                 self.error(_("You must enter a executable"))
    743                 return True
    744             policy = generate.policy(name, self.get_type())
    745             policy.set_program(exe)
    746             policy.gen_writeable()
    747             policy.gen_symbols()
    748             for f in policy.files.keys():
    749                 iter = self.store.append()
    750                 self.store.set_value(iter, 0, f)
    751                 self.store.set_value(iter, 1, FILE)
    752 
    753             for f in policy.dirs.keys():
    754                 iter = self.store.append()
    755                 self.store.set_value(iter, 0, f)
    756                 self.store.set_value(iter, 1, DIR)
    757             self.tmp_checkbutton.set_active(policy.use_tmp)
    758             self.uid_checkbutton.set_active(policy.use_uid)
    759             self.pam_checkbutton.set_active(policy.use_pam)
    760             self.dbus_checkbutton.set_active(policy.use_dbus)
    761             self.audit_checkbutton.set_active(policy.use_audit)
    762             self.terminal_checkbutton.set_active(policy.use_terminal)
    763             self.mail_checkbutton.set_active(policy.use_mail)
    764             self.syslog_checkbutton.set_active(policy.use_syslog)
    765 
    766     def stand_alone(self):
    767         desktopName = _("Configue SELinux")
    768 
    769         self.setupScreen()
    770         self.mainWindow.connect("destroy", self.quit)
    771 
    772         self.mainWindow.show_all()
    773         Gtk.main()
    774 
    775 if __name__ == "__main__":
    776     signal.signal(signal.SIGINT, signal.SIG_DFL)
    777 
    778     app = childWindow()
    779     app.stand_alone()
    780