261 lines
10 KiB
Python
261 lines
10 KiB
Python
## portsPage.py - show selinux mappings
|
|
## Copyright (C) 2006 Red Hat, Inc.
|
|
|
|
## This program is free software; you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation; either version 2 of the License, or
|
|
## (at your option) any later version.
|
|
|
|
## This program is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with this program; if not, write to the Free Software
|
|
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
## Author: Dan Walsh
|
|
import string
|
|
import gtk
|
|
import gtk.glade
|
|
import os
|
|
import gobject
|
|
import sys
|
|
import seobject
|
|
import commands
|
|
from semanagePage import *
|
|
|
|
##
|
|
## I18N
|
|
##
|
|
PROGNAME = "policycoreutils"
|
|
import gettext
|
|
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
|
|
gettext.textdomain(PROGNAME)
|
|
TYPE_COL = 0
|
|
PROTOCOL_COL = 1
|
|
MLS_COL = 2
|
|
PORT_COL = 3
|
|
try:
|
|
gettext.install(PROGNAME,
|
|
localedir="/usr/share/locale",
|
|
unicode=False,
|
|
codeset='utf-8')
|
|
except IOError:
|
|
import __builtin__
|
|
__builtin__.__dict__['_'] = unicode
|
|
|
|
|
|
class portsPage(semanagePage):
|
|
|
|
def __init__(self, xml):
|
|
semanagePage.__init__(self, xml, "ports", _("Network Port"))
|
|
xml.signal_connect("on_group_clicked", self.on_group_clicked)
|
|
self.group = False
|
|
self.ports_filter = xml.get_widget("portsFilterEntry")
|
|
self.ports_filter.connect("focus_out_event", self.filter_changed)
|
|
self.ports_filter.connect("activate", self.filter_changed)
|
|
self.ports_name_entry = xml.get_widget("portsNameEntry")
|
|
self.ports_protocol_combo = xml.get_widget("portsProtocolCombo")
|
|
self.ports_number_entry = xml.get_widget("portsNumberEntry")
|
|
self.ports_mls_entry = xml.get_widget("portsMLSEntry")
|
|
self.ports_add_button = xml.get_widget("portsAddButton")
|
|
self.ports_properties_button = xml.get_widget("portsPropertiesButton")
|
|
self.ports_delete_button = xml.get_widget("portsDeleteButton")
|
|
liststore = self.ports_protocol_combo.get_model()
|
|
iter = liststore.get_iter_first()
|
|
self.ports_protocol_combo.set_active_iter(iter)
|
|
self.init_store()
|
|
self.edit = True
|
|
self.load()
|
|
|
|
def filter_changed(self, *arg):
|
|
filter = arg[0].get_text()
|
|
if filter != self.filter:
|
|
if self.edit:
|
|
self.load(filter)
|
|
else:
|
|
self.group_load(filter)
|
|
|
|
def init_store(self):
|
|
self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
|
|
self.view.set_model(self.store)
|
|
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
|
|
|
|
self.view.set_search_equal_func(self.search)
|
|
col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL)
|
|
col.set_sort_column_id(TYPE_COL)
|
|
col.set_resizable(True)
|
|
self.view.append_column(col)
|
|
self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING)
|
|
|
|
col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL)
|
|
col.set_sort_column_id(PROTOCOL_COL)
|
|
col.set_resizable(True)
|
|
self.view.append_column(col)
|
|
|
|
self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL)
|
|
self.mls_col.set_resizable(True)
|
|
self.mls_col.set_sort_column_id(MLS_COL)
|
|
self.view.append_column(self.mls_col)
|
|
|
|
col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL)
|
|
col.set_sort_column_id(PORT_COL)
|
|
col.set_resizable(True)
|
|
self.view.append_column(col)
|
|
self.store.set_sort_func(PORT_COL, self.sort_int, "")
|
|
|
|
def sort_int(self, treemodel, iter1, iter2, user_data):
|
|
try:
|
|
p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0])
|
|
p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0])
|
|
if p1 > p2:
|
|
return 1
|
|
if p1 == p2:
|
|
return 0
|
|
return -1
|
|
except:
|
|
return 0
|
|
|
|
def load(self, filter=""):
|
|
self.filter = filter
|
|
self.port = seobject.portRecords()
|
|
dict = self.port.get_all(self.local)
|
|
keys = dict.keys()
|
|
keys.sort()
|
|
self.store.clear()
|
|
for k in keys:
|
|
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)):
|
|
continue
|
|
iter = self.store.append()
|
|
if k[0] == k[1]:
|
|
self.store.set_value(iter, PORT_COL, k[0])
|
|
else:
|
|
rec = "%s-%s" % k[:2]
|
|
self.store.set_value(iter, PORT_COL, rec)
|
|
self.store.set_value(iter, TYPE_COL, dict[k][0])
|
|
self.store.set_value(iter, PROTOCOL_COL, k[2])
|
|
self.store.set_value(iter, MLS_COL, dict[k][1])
|
|
self.view.get_selection().select_path((0,))
|
|
|
|
def group_load(self, filter=""):
|
|
self.filter = filter
|
|
self.port = seobject.portRecords()
|
|
dict = self.port.get_all_by_type(self.local)
|
|
keys = dict.keys()
|
|
keys.sort()
|
|
self.store.clear()
|
|
for k in keys:
|
|
ports_string = ", ".join(dict[k])
|
|
if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)):
|
|
continue
|
|
iter = self.store.append()
|
|
self.store.set_value(iter, TYPE_COL, k[0])
|
|
self.store.set_value(iter, PROTOCOL_COL, k[1])
|
|
self.store.set_value(iter, PORT_COL, ports_string)
|
|
self.store.set_value(iter, MLS_COL, "")
|
|
self.view.get_selection().select_path((0,))
|
|
|
|
def propertiesDialog(self):
|
|
if self.edit:
|
|
semanagePage.propertiesDialog(self)
|
|
|
|
def dialogInit(self):
|
|
store, iter = self.view.get_selection().get_selected()
|
|
self.ports_number_entry.set_text(store.get_value(iter, PORT_COL))
|
|
self.ports_number_entry.set_sensitive(False)
|
|
self.ports_protocol_combo.set_sensitive(False)
|
|
self.ports_name_entry.set_text(store.get_value(iter, TYPE_COL))
|
|
self.ports_mls_entry.set_text(store.get_value(iter, MLS_COL))
|
|
protocol = store.get_value(iter, PROTOCOL_COL)
|
|
liststore = self.ports_protocol_combo.get_model()
|
|
iter = liststore.get_iter_first()
|
|
while iter != None and liststore.get_value(iter, 0) != protocol:
|
|
iter = liststore.iter_next(iter)
|
|
if iter != None:
|
|
self.ports_protocol_combo.set_active_iter(iter)
|
|
|
|
def dialogClear(self):
|
|
self.ports_number_entry.set_text("")
|
|
self.ports_number_entry.set_sensitive(True)
|
|
self.ports_protocol_combo.set_sensitive(True)
|
|
self.ports_name_entry.set_text("")
|
|
self.ports_mls_entry.set_text("s0")
|
|
|
|
def delete(self):
|
|
store, iter = self.view.get_selection().get_selected()
|
|
port = store.get_value(iter, PORT_COL)
|
|
protocol = store.get_value(iter, 1)
|
|
try:
|
|
self.wait()
|
|
(rc, out) = commands.getstatusoutput("semanage port -d -p %s %s" % (protocol, port))
|
|
self.ready()
|
|
if rc != 0:
|
|
return self.error(out)
|
|
store.remove(iter)
|
|
self.view.get_selection().select_path((0,))
|
|
except ValueError, e:
|
|
self.error(e.args[0])
|
|
|
|
def add(self):
|
|
target = self.ports_name_entry.get_text().strip()
|
|
mls = self.ports_mls_entry.get_text().strip()
|
|
port_number = self.ports_number_entry.get_text().strip()
|
|
if port_number == "":
|
|
port_number = "1"
|
|
for i in port_number.split("-"):
|
|
if not i.isdigit():
|
|
self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number)
|
|
return False
|
|
list_model = self.ports_protocol_combo.get_model()
|
|
iter = self.ports_protocol_combo.get_active_iter()
|
|
protocol = list_model.get_value(iter, 0)
|
|
self.wait()
|
|
(rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
|
|
self.ready()
|
|
if rc != 0:
|
|
self.error(out)
|
|
return False
|
|
iter = self.store.append()
|
|
|
|
self.store.set_value(iter, TYPE_COL, target)
|
|
self.store.set_value(iter, PORT_COL, port_number)
|
|
self.store.set_value(iter, PROTOCOL_COL, protocol)
|
|
self.store.set_value(iter, MLS_COL, mls)
|
|
|
|
def modify(self):
|
|
target = self.ports_name_entry.get_text().strip()
|
|
mls = self.ports_mls_entry.get_text().strip()
|
|
port_number = self.ports_number_entry.get_text().strip()
|
|
list_model = self.ports_protocol_combo.get_model()
|
|
iter = self.ports_protocol_combo.get_active_iter()
|
|
protocol = list_model.get_value(iter, 0)
|
|
self.wait()
|
|
(rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
|
|
self.ready()
|
|
if rc != 0:
|
|
self.error(out)
|
|
return False
|
|
store, iter = self.view.get_selection().get_selected()
|
|
self.store.set_value(iter, TYPE_COL, target)
|
|
self.store.set_value(iter, PORT_COL, port_number)
|
|
self.store.set_value(iter, PROTOCOL_COL, protocol)
|
|
self.store.set_value(iter, MLS_COL, mls)
|
|
|
|
def on_group_clicked(self, button):
|
|
self.ports_add_button.set_sensitive(self.group)
|
|
self.ports_properties_button.set_sensitive(self.group)
|
|
self.ports_delete_button.set_sensitive(self.group)
|
|
self.mls_col.set_visible(self.group)
|
|
|
|
self.group = not self.group
|
|
if self.group:
|
|
button.set_label(_("List View"))
|
|
self.group_load(self.filter)
|
|
else:
|
|
button.set_label(_("Group View"))
|
|
self.load(self.filter)
|
|
|
|
return True
|