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