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