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