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