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