1 ## portsPage.py - show selinux mappings 2 ## Copyright (C) 2006 Red Hat, Inc. 3 4 ## This program is free software; you can redistribute it and/or modify 5 ## it under the terms of the GNU General Public License as published by 6 ## the Free Software Foundation; either version 2 of the License, or 7 ## (at your option) any later version. 8 9 ## This program is distributed in the hope that it will be useful, 10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 ## GNU General Public License for more details. 13 14 ## You should have received a copy of the GNU General Public License 15 ## along with this program; if not, write to the Free Software 16 ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 18 ## Author: Dan Walsh 19 import string 20 import gtk 21 import gtk.glade 22 import os 23 import gobject 24 import sys 25 import seobject 26 import commands 27 from semanagePage import * 28 29 ## 30 ## I18N 31 ## 32 PROGNAME = "policycoreutils" 33 import gettext 34 gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 35 gettext.textdomain(PROGNAME) 36 TYPE_COL = 0 37 PROTOCOL_COL = 1 38 MLS_COL = 2 39 PORT_COL = 3 40 try: 41 gettext.install(PROGNAME, 42 localedir="/usr/share/locale", 43 unicode=False, 44 codeset='utf-8') 45 except IOError: 46 import __builtin__ 47 __builtin__.__dict__['_'] = unicode 48 49 50 class portsPage(semanagePage): 51 52 def __init__(self, xml): 53 semanagePage.__init__(self, xml, "ports", _("Network Port")) 54 xml.signal_connect("on_group_clicked", self.on_group_clicked) 55 self.group = False 56 self.ports_filter = xml.get_widget("portsFilterEntry") 57 self.ports_filter.connect("focus_out_event", self.filter_changed) 58 self.ports_filter.connect("activate", self.filter_changed) 59 self.ports_name_entry = xml.get_widget("portsNameEntry") 60 self.ports_protocol_combo = xml.get_widget("portsProtocolCombo") 61 self.ports_number_entry = xml.get_widget("portsNumberEntry") 62 self.ports_mls_entry = xml.get_widget("portsMLSEntry") 63 self.ports_add_button = xml.get_widget("portsAddButton") 64 self.ports_properties_button = xml.get_widget("portsPropertiesButton") 65 self.ports_delete_button = xml.get_widget("portsDeleteButton") 66 liststore = self.ports_protocol_combo.get_model() 67 iter = liststore.get_iter_first() 68 self.ports_protocol_combo.set_active_iter(iter) 69 self.init_store() 70 self.edit = True 71 self.load() 72 73 def filter_changed(self, *arg): 74 filter = arg[0].get_text() 75 if filter != self.filter: 76 if self.edit: 77 self.load(filter) 78 else: 79 self.group_load(filter) 80 81 def init_store(self): 82 self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) 83 self.view.set_model(self.store) 84 self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) 85 86 self.view.set_search_equal_func(self.search) 87 col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL) 88 col.set_sort_column_id(TYPE_COL) 89 col.set_resizable(True) 90 self.view.append_column(col) 91 self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING) 92 93 col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL) 94 col.set_sort_column_id(PROTOCOL_COL) 95 col.set_resizable(True) 96 self.view.append_column(col) 97 98 self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL) 99 self.mls_col.set_resizable(True) 100 self.mls_col.set_sort_column_id(MLS_COL) 101 self.view.append_column(self.mls_col) 102 103 col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL) 104 col.set_sort_column_id(PORT_COL) 105 col.set_resizable(True) 106 self.view.append_column(col) 107 self.store.set_sort_func(PORT_COL, self.sort_int, "") 108 109 def sort_int(self, treemodel, iter1, iter2, user_data): 110 try: 111 p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0]) 112 p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0]) 113 if p1 > p2: 114 return 1 115 if p1 == p2: 116 return 0 117 return -1 118 except: 119 return 0 120 121 def load(self, filter=""): 122 self.filter = filter 123 self.port = seobject.portRecords() 124 dict = self.port.get_all(self.local) 125 keys = dict.keys() 126 keys.sort() 127 self.store.clear() 128 for k in keys: 129 if not (self.match(str(k[0]), filter) or self.match(dict[k][0], filter) or self.match(k[2], filter) or self.match(dict[k][1], filter) or self.match(dict[k][1], filter)): 130 continue 131 iter = self.store.append() 132 if k[0] == k[1]: 133 self.store.set_value(iter, PORT_COL, k[0]) 134 else: 135 rec = "%s-%s" % k[:2] 136 self.store.set_value(iter, PORT_COL, rec) 137 self.store.set_value(iter, TYPE_COL, dict[k][0]) 138 self.store.set_value(iter, PROTOCOL_COL, k[2]) 139 self.store.set_value(iter, MLS_COL, dict[k][1]) 140 self.view.get_selection().select_path((0,)) 141 142 def group_load(self, filter=""): 143 self.filter = filter 144 self.port = seobject.portRecords() 145 dict = self.port.get_all_by_type(self.local) 146 keys = dict.keys() 147 keys.sort() 148 self.store.clear() 149 for k in keys: 150 ports_string = ", ".join(dict[k]) 151 if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)): 152 continue 153 iter = self.store.append() 154 self.store.set_value(iter, TYPE_COL, k[0]) 155 self.store.set_value(iter, PROTOCOL_COL, k[1]) 156 self.store.set_value(iter, PORT_COL, ports_string) 157 self.store.set_value(iter, MLS_COL, "") 158 self.view.get_selection().select_path((0,)) 159 160 def propertiesDialog(self): 161 if self.edit: 162 semanagePage.propertiesDialog(self) 163 164 def dialogInit(self): 165 store, iter = self.view.get_selection().get_selected() 166 self.ports_number_entry.set_text(store.get_value(iter, PORT_COL)) 167 self.ports_number_entry.set_sensitive(False) 168 self.ports_protocol_combo.set_sensitive(False) 169 self.ports_name_entry.set_text(store.get_value(iter, TYPE_COL)) 170 self.ports_mls_entry.set_text(store.get_value(iter, MLS_COL)) 171 protocol = store.get_value(iter, PROTOCOL_COL) 172 liststore = self.ports_protocol_combo.get_model() 173 iter = liststore.get_iter_first() 174 while iter != None and liststore.get_value(iter, 0) != protocol: 175 iter = liststore.iter_next(iter) 176 if iter != None: 177 self.ports_protocol_combo.set_active_iter(iter) 178 179 def dialogClear(self): 180 self.ports_number_entry.set_text("") 181 self.ports_number_entry.set_sensitive(True) 182 self.ports_protocol_combo.set_sensitive(True) 183 self.ports_name_entry.set_text("") 184 self.ports_mls_entry.set_text("s0") 185 186 def delete(self): 187 store, iter = self.view.get_selection().get_selected() 188 port = store.get_value(iter, PORT_COL) 189 protocol = store.get_value(iter, 1) 190 try: 191 self.wait() 192 (rc, out) = commands.getstatusoutput("semanage port -d -p %s %s" % (protocol, port)) 193 self.ready() 194 if rc != 0: 195 return self.error(out) 196 store.remove(iter) 197 self.view.get_selection().select_path((0,)) 198 except ValueError, e: 199 self.error(e.args[0]) 200 201 def add(self): 202 target = self.ports_name_entry.get_text().strip() 203 mls = self.ports_mls_entry.get_text().strip() 204 port_number = self.ports_number_entry.get_text().strip() 205 if port_number == "": 206 port_number = "1" 207 for i in port_number.split("-"): 208 if not i.isdigit(): 209 self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number) 210 return False 211 list_model = self.ports_protocol_combo.get_model() 212 iter = self.ports_protocol_combo.get_active_iter() 213 protocol = list_model.get_value(iter, 0) 214 self.wait() 215 (rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number)) 216 self.ready() 217 if rc != 0: 218 self.error(out) 219 return False 220 iter = self.store.append() 221 222 self.store.set_value(iter, TYPE_COL, target) 223 self.store.set_value(iter, PORT_COL, port_number) 224 self.store.set_value(iter, PROTOCOL_COL, protocol) 225 self.store.set_value(iter, MLS_COL, mls) 226 227 def modify(self): 228 target = self.ports_name_entry.get_text().strip() 229 mls = self.ports_mls_entry.get_text().strip() 230 port_number = self.ports_number_entry.get_text().strip() 231 list_model = self.ports_protocol_combo.get_model() 232 iter = self.ports_protocol_combo.get_active_iter() 233 protocol = list_model.get_value(iter, 0) 234 self.wait() 235 (rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number)) 236 self.ready() 237 if rc != 0: 238 self.error(out) 239 return False 240 store, iter = self.view.get_selection().get_selected() 241 self.store.set_value(iter, TYPE_COL, target) 242 self.store.set_value(iter, PORT_COL, port_number) 243 self.store.set_value(iter, PROTOCOL_COL, protocol) 244 self.store.set_value(iter, MLS_COL, mls) 245 246 def on_group_clicked(self, button): 247 self.ports_add_button.set_sensitive(self.group) 248 self.ports_properties_button.set_sensitive(self.group) 249 self.ports_delete_button.set_sensitive(self.group) 250 self.mls_col.set_visible(self.group) 251 252 self.group = not self.group 253 if self.group: 254 button.set_label(_("List View")) 255 self.group_load(self.filter) 256 else: 257 button.set_label(_("Group View")) 258 self.load(self.filter) 259 260 return True 261