blob: 30f58383bc1de76357f0edea6e1143707f1080d4 [file] [log] [blame]
Dan Walsh514af852012-04-13 11:04:45 -04001## 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
Dan Walsh514af852012-04-13 11:04:45 -040019import sys
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020020from gi.repository import GObject, Gtk
Dan Walsh514af852012-04-13 11:04:45 -040021import seobject
Vit Mojzis530904e2016-10-19 14:36:03 +020022
23TYPE_COL = 0
24PROTOCOL_COL = 1
25MLS_COL = 2
26PORT_COL = 3
27
Jason Zaman05d1cea2016-08-05 02:34:04 +080028try:
29 from subprocess import getstatusoutput
30except ImportError:
31 from commands import getstatusoutput
32
Jason Zaman789d0eb2015-07-24 16:07:13 +080033from semanagePage import *
Dan Walsh514af852012-04-13 11:04:45 -040034
35##
36## I18N
37##
38PROGNAME = "policycoreutils"
Dan Walsh514af852012-04-13 11:04:45 -040039try:
Jason Zamanaf595442016-08-05 02:34:02 +080040 import gettext
41 kwargs = {}
42 if sys.version_info < (3,):
43 kwargs['unicode'] = True
Dan Walsh514af852012-04-13 11:04:45 -040044 gettext.install(PROGNAME,
45 localedir="/usr/share/locale",
Jason Zamanaf595442016-08-05 02:34:02 +080046 codeset='utf-8',
47 **kwargs)
48except:
49 try:
50 import builtins
51 builtins.__dict__['_'] = str
52 except ImportError:
53 import __builtin__
54 __builtin__.__dict__['_'] = unicode
Dan Walsh514af852012-04-13 11:04:45 -040055
Jason Zaman789d0eb2015-07-24 16:07:13 +080056
Dan Walsh514af852012-04-13 11:04:45 -040057class portsPage(semanagePage):
Jason Zaman789d0eb2015-07-24 16:07:13 +080058
Dan Walsh514af852012-04-13 11:04:45 -040059 def __init__(self, xml):
60 semanagePage.__init__(self, xml, "ports", _("Network Port"))
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020061 group_listview = xml.get_object("listViewButton")
62 group_listview.connect("clicked", self.on_group_clicked)
Dan Walsh514af852012-04-13 11:04:45 -040063 self.group = False
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020064 self.ports_filter = xml.get_object("portsFilterEntry")
Dan Walsh514af852012-04-13 11:04:45 -040065 self.ports_filter.connect("focus_out_event", self.filter_changed)
66 self.ports_filter.connect("activate", self.filter_changed)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020067 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")
Dan Walsh514af852012-04-13 11:04:45 -040074 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):
Jason Zaman789d0eb2015-07-24 16:07:13 +080082 filter = arg[0].get_text()
Dan Walsh514af852012-04-13 11:04:45 -040083 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):
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020090 self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
Dan Walsh514af852012-04-13 11:04:45 -040091 self.view.set_model(self.store)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020092 self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING)
Dan Walsh514af852012-04-13 11:04:45 -040093
94 self.view.set_search_equal_func(self.search)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020095 col = Gtk.TreeViewColumn(_("SELinux Port\nType"), Gtk.CellRendererText(), text=TYPE_COL)
Dan Walsh514af852012-04-13 11:04:45 -040096 col.set_sort_column_id(TYPE_COL)
97 col.set_resizable(True)
98 self.view.append_column(col)
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +020099 self.store.set_sort_column_id(TYPE_COL, Gtk.SortType.ASCENDING)
Dan Walsh514af852012-04-13 11:04:45 -0400100
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200101 col = Gtk.TreeViewColumn(_("Protocol"), Gtk.CellRendererText(), text=PROTOCOL_COL)
Dan Walsh514af852012-04-13 11:04:45 -0400102 col.set_sort_column_id(PROTOCOL_COL)
103 col.set_resizable(True)
104 self.view.append_column(col)
105
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200106 self.mls_col = Gtk.TreeViewColumn(_("MLS/MCS\nLevel"), Gtk.CellRendererText(), text=MLS_COL)
Dan Walsh514af852012-04-13 11:04:45 -0400107 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
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200111 col = Gtk.TreeViewColumn(_("Port"), Gtk.CellRendererText(), text=PORT_COL)
Dan Walsh514af852012-04-13 11:04:45 -0400112 col.set_sort_column_id(PORT_COL)
113 col.set_resizable(True)
114 self.view.append_column(col)
Jason Zaman789d0eb2015-07-24 16:07:13 +0800115 self.store.set_sort_func(PORT_COL, self.sort_int, "")
Dan Walsh514af852012-04-13 11:04:45 -0400116
117 def sort_int(self, treemodel, iter1, iter2, user_data):
118 try:
Jason Zaman789d0eb2015-07-24 16:07:13 +0800119 p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0])
120 p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0])
Dan Walsh514af852012-04-13 11:04:45 -0400121 if p1 > p2:
122 return 1
123 if p1 == p2:
124 return 0
125 return -1
126 except:
127 return 0
128
Jason Zaman789d0eb2015-07-24 16:07:13 +0800129 def load(self, filter=""):
130 self.filter = filter
Dan Walsh514af852012-04-13 11:04:45 -0400131 self.port = seobject.portRecords()
132 dict = self.port.get_all(self.local)
Dan Walsh514af852012-04-13 11:04:45 -0400133 self.store.clear()
Jason Zaman4d340e42016-08-05 02:34:03 +0800134 for k in sorted(dict.keys()):
Dan Walsh514af852012-04-13 11:04:45 -0400135 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]:
Nicolas Iooss0f3beeb2017-09-20 08:56:54 +0200139 self.store.set_value(iter, PORT_COL, str(k[0]))
Dan Walsh514af852012-04-13 11:04:45 -0400140 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])
Jason Zaman789d0eb2015-07-24 16:07:13 +0800146 self.view.get_selection().select_path((0,))
Dan Walsh514af852012-04-13 11:04:45 -0400147
Jason Zaman789d0eb2015-07-24 16:07:13 +0800148 def group_load(self, filter=""):
149 self.filter = filter
Dan Walsh514af852012-04-13 11:04:45 -0400150 self.port = seobject.portRecords()
151 dict = self.port.get_all_by_type(self.local)
Dan Walsh514af852012-04-13 11:04:45 -0400152 self.store.clear()
Jason Zaman4d340e42016-08-05 02:34:03 +0800153 for k in sorted(dict.keys()):
Dan Walsh514af852012-04-13 11:04:45 -0400154 ports_string = ", ".join(dict[k])
Jason Zaman789d0eb2015-07-24 16:07:13 +0800155 if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)):
Dan Walsh514af852012-04-13 11:04:45 -0400156 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, "")
Jason Zaman789d0eb2015-07-24 16:07:13 +0800162 self.view.get_selection().select_path((0,))
Dan Walsh514af852012-04-13 11:04:45 -0400163
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()
Jason Zaman789d0eb2015-07-24 16:07:13 +0800178 while iter != None and liststore.get_value(iter, 0) != protocol:
Dan Walsh514af852012-04-13 11:04:45 -0400179 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()
Jason Zaman05d1cea2016-08-05 02:34:04 +0800196 (rc, out) = getstatusoutput("semanage port -d -p %s %s" % (protocol, port))
Dan Walsh514af852012-04-13 11:04:45 -0400197 self.ready()
198 if rc != 0:
199 return self.error(out)
200 store.remove(iter)
Jason Zaman789d0eb2015-07-24 16:07:13 +0800201 self.view.get_selection().select_path((0,))
Jason Zaman4d340e42016-08-05 02:34:03 +0800202 except ValueError as e:
Dan Walsh514af852012-04-13 11:04:45 -0400203 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():
Jason Zaman789d0eb2015-07-24 16:07:13 +0800213 self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number)
Dan Walsh514af852012-04-13 11:04:45 -0400214 return False
215 list_model = self.ports_protocol_combo.get_model()
216 iter = self.ports_protocol_combo.get_active_iter()
Jason Zaman789d0eb2015-07-24 16:07:13 +0800217 protocol = list_model.get_value(iter, 0)
Dan Walsh514af852012-04-13 11:04:45 -0400218 self.wait()
Jason Zaman05d1cea2016-08-05 02:34:04 +0800219 (rc, out) = getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
Dan Walsh514af852012-04-13 11:04:45 -0400220 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()
Jason Zaman789d0eb2015-07-24 16:07:13 +0800237 protocol = list_model.get_value(iter, 0)
Dan Walsh514af852012-04-13 11:04:45 -0400238 self.wait()
Jason Zaman05d1cea2016-08-05 02:34:04 +0800239 (rc, out) = getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
Dan Walsh514af852012-04-13 11:04:45 -0400240 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