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