Home | History | Annotate | Download | only in gui
      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