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