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