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