xref: /aosp_15_r20/external/selinux/gui/fcontextPage.py (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1## fcontextPage.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
19from gi.repository import GObject, Gtk
20import seobject
21try:
22    from subprocess import getstatusoutput
23except ImportError:
24    from commands import getstatusoutput
25
26from semanagePage import *
27
28SPEC_COL = 0
29TYPE_COL = 1
30FTYPE_COL = 2
31
32
33class context:
34
35    def __init__(self, scontext):
36        self.scontext = scontext
37        con = scontext.split(":")
38        self.type = con[0]
39        if len(con) > 1:
40            self.mls = con[1]
41        else:
42            self.mls = "s0"
43
44    def __str__(self):
45        return self.scontext
46
47##
48## I18N
49##
50PROGNAME = "selinux-gui"
51try:
52    import gettext
53    kwargs = {}
54    if sys.version_info < (3,):
55        kwargs['unicode'] = True
56    t = gettext.translation(PROGNAME,
57                    localedir="/usr/share/locale",
58                    **kwargs,
59                    fallback=True)
60    _ = t.gettext
61except:
62    try:
63        import builtins
64        builtins.__dict__['_'] = str
65    except ImportError:
66        import __builtin__
67        __builtin__.__dict__['_'] = unicode
68
69
70class fcontextPage(semanagePage):
71
72    def __init__(self, xml):
73        semanagePage.__init__(self, xml, "fcontext", _("File Labeling"))
74        self.fcontextFilter = xml.get_object("fcontextFilterEntry")
75        self.fcontextFilter.connect("focus_out_event", self.filter_changed)
76        self.fcontextFilter.connect("activate", self.filter_changed)
77
78        self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING)
79        self.view = xml.get_object("fcontextView")
80        self.view.set_model(self.store)
81        self.view.set_search_equal_func(self.search)
82
83        col = Gtk.TreeViewColumn(_("File\nSpecification"), Gtk.CellRendererText(), text=SPEC_COL)
84        col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
85        col.set_fixed_width(250)
86
87        col.set_sort_column_id(SPEC_COL)
88        col.set_resizable(True)
89        self.view.append_column(col)
90        col = Gtk.TreeViewColumn(_("Selinux\nFile Type"), Gtk.CellRendererText(), text=TYPE_COL)
91
92        col.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
93        col.set_fixed_width(250)
94        col.set_sort_column_id(TYPE_COL)
95        col.set_resizable(True)
96        self.view.append_column(col)
97        col = Gtk.TreeViewColumn(_("File\nType"), Gtk.CellRendererText(), text=2)
98        col.set_sort_column_id(FTYPE_COL)
99        col.set_resizable(True)
100        self.view.append_column(col)
101
102        self.store.set_sort_column_id(SPEC_COL, Gtk.SortType.ASCENDING)
103        self.load()
104        self.fcontextEntry = xml.get_object("fcontextEntry")
105        self.fcontextFileTypeCombo = xml.get_object("fcontextFileTypeCombo")
106        # Populate file type combo_box
107        liststore = self.fcontextFileTypeCombo.get_model()
108        for ftype in seobject.file_type_str_to_option.keys():
109            iter = liststore.append()
110            liststore.set_value(iter, 0, ftype)
111        iter = liststore.get_iter_first()
112        self.fcontextFileTypeCombo.set_active_iter(iter)
113        self.fcontextTypeEntry = xml.get_object("fcontextTypeEntry")
114        self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry")
115
116    def match(self, fcon_dict, k, filter):
117        try:
118            f = filter.lower()
119            for con in k:
120                k = con.lower()
121                if k.find(f) >= 0:
122                    return True
123            for con in fcon_dict[k]:
124                k = con.lower()
125                if k.find(f) >= 0:
126                    return True
127        except:
128            pass
129        return False
130
131    def load(self, filter=""):
132        self.filter = filter
133        self.fcontext = seobject.fcontextRecords()
134        self.store.clear()
135        fcon_dict = self.fcontext.get_all(self.local)
136        if self.local:
137            fkeys = fcon_dict.keys()
138        else:
139            fkeys = sorted(fcon_dict.keys())
140        for k in fkeys:
141            if not self.match(fcon_dict, k, filter):
142                continue
143            iter = self.store.append()
144            self.store.set_value(iter, SPEC_COL, k[0])
145            self.store.set_value(iter, FTYPE_COL, k[1])
146            if fcon_dict[k]:
147                rec = "%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3], False))
148            else:
149                rec = "<<None>>"
150            self.store.set_value(iter, TYPE_COL, rec)
151        self.view.get_selection().select_path((0,))
152
153    def filter_changed(self, *arg):
154        filter = arg[0].get_text()
155        if filter != self.filter:
156            self.load(filter)
157
158    def dialogInit(self):
159        store, iter = self.view.get_selection().get_selected()
160        self.fcontextEntry.set_text(store.get_value(iter, SPEC_COL))
161        self.fcontextEntry.set_sensitive(False)
162        scontext = store.get_value(iter, TYPE_COL)
163        scon = context(scontext)
164        self.fcontextTypeEntry.set_text(scon.type)
165        self.fcontextMLSEntry.set_text(scon.mls)
166        type = store.get_value(iter, FTYPE_COL)
167        liststore = self.fcontextFileTypeCombo.get_model()
168        iter = liststore.get_iter_first()
169        while iter != None and liststore.get_value(iter, 0) != type:
170            iter = liststore.iter_next(iter)
171        if iter != None:
172            self.fcontextFileTypeCombo.set_active_iter(iter)
173        self.fcontextFileTypeCombo.set_sensitive(False)
174
175    def dialogClear(self):
176        self.fcontextEntry.set_text("")
177        self.fcontextEntry.set_sensitive(True)
178        self.fcontextFileTypeCombo.set_sensitive(True)
179        self.fcontextFileTypeCombo.set_active(0)
180        self.fcontextTypeEntry.set_text("")
181        self.fcontextMLSEntry.set_text("s0")
182
183    def delete(self):
184        store, iter = self.view.get_selection().get_selected()
185        try:
186            fspec = store.get_value(iter, SPEC_COL)
187            ftype = store.get_value(iter, FTYPE_COL)
188            self.wait()
189            (rc, out) = getstatusoutput("semanage fcontext -d -f '%s' '%s'" % (seobject.file_type_str_to_option[ftype], fspec))
190            self.ready()
191
192            if rc != 0:
193                return self.error(out)
194            store.remove(iter)
195            self.view.get_selection().select_path((0,))
196        except ValueError as e:
197            self.error(e.args[0])
198
199    def add(self):
200        fspec = self.fcontextEntry.get_text().strip()
201        type = self.fcontextTypeEntry.get_text().strip()
202        mls = self.fcontextMLSEntry.get_text().strip()
203        list_model = self.fcontextFileTypeCombo.get_model()
204        it = self.fcontextFileTypeCombo.get_active_iter()
205        ftype = list_model.get_value(it, 0)
206        self.wait()
207        (rc, out) = getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, seobject.file_type_str_to_option[ftype], fspec))
208        self.ready()
209        if rc != 0:
210            self.error(out)
211            return False
212
213        iter = self.store.append()
214        self.store.set_value(iter, SPEC_COL, fspec)
215        self.store.set_value(iter, FTYPE_COL, ftype)
216        self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls))
217
218    def modify(self):
219        fspec = self.fcontextEntry.get_text().strip()
220        type = self.fcontextTypeEntry.get_text().strip()
221        mls = self.fcontextMLSEntry.get_text().strip()
222        list_model = self.fcontextFileTypeCombo.get_model()
223        iter = self.fcontextFileTypeCombo.get_active_iter()
224        ftype = list_model.get_value(iter, 0)
225        self.wait()
226        (rc, out) = getstatusoutput("semanage fcontext -m -t %s -r %s -f '%s' '%s'" % (type, mls, seobject.file_type_str_to_option[ftype], fspec))
227        self.ready()
228        if rc != 0:
229            self.error(out)
230            return False
231
232        store, iter = self.view.get_selection().get_selected()
233        self.store.set_value(iter, SPEC_COL, fspec)
234        self.store.set_value(iter, FTYPE_COL, ftype)
235        self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls))
236