|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/share/system-config-securitylevel/ |
Upload File : |
#
# selinuxPage.py - GUI for SELinux page in system-config-securitylevel
#
# Brent Fox <bfox@redhat.com>
# Dan Walsh <dwalsh@redhat.com>
#
# Copyright 2004 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import string
import gtk
import gtk.glade
import os
import libxml2
import gobject
import sys
import tempfile
INSTALLPATH='/usr/share/system-config-securitylevel'
sys.path.append(INSTALLPATH)
rhplPath="/usr/lib/python%d.%d/site-packages/rhpl" % (sys.version_info[0], sys.version_info[1])
if not rhplPath in sys.path:
sys.path.append(rhplPath)
rhplPath="/usr/lib64/python%d.%d/site-packages/rhpl" % (sys.version_info[0], sys.version_info[1])
if not rhplPath in sys.path:
sys.path.append(rhplPath)
from Conf import *
import commands
ENFORCING=0
PERMISSIVE=1
DISABLED=2
SELINUXDIR="/etc/selinux/"
RELABELFILE="/.autorelabel"
##
## I18N
##
from rhpl.translate import _, N_
import rhpl.translate as translate
domain = "system-config-securitylevel"
translate.textdomain (domain)
class Translation:
def __init__(self):
self.translation={}
fd=open(INSTALLPATH + "/selinux.tbl","r")
lines=fd.readlines()
fd.close()
for i in lines:
try:
line=i.strip().split("_(\"")
key=line[0].strip()
category=line[1].split("\"")[0]
value=line[2].split("\"")[0]
self.translation[key]=(category,value)
except:
continue
def get_category(self,key):
try:
return _(self.translation[key][0])
except:
return _("Other")
def get_value(self,key):
try:
return _(self.translation[key][1])
except:
return key
class Modifier:
def __init__(self,name, on, save):
self.on=on
self.name=name
self.save=save
def set(self,value):
self.on=value
self.save=True
def isOn(self):
return self.on
class Boolean(Modifier):
def __init__(self,name, val, save=False):
Modifier.__init__(self,name, val, save)
class Modifiers:
def __init__(self,store):
self.modifiers={}
self.translation=Translation()
self.store=store
self.store.clear()
self.booleanDirty=False
def add(self,name,val):
if name == "targeted_policy":
return
category=self.translation.get_category(name)
if not self.modifiers.has_key(category):
self.modifiers[category]={}
iter=self.store.append(None)
self.modifiers[category]["iter"] = iter
self.store.set_value(iter, 1, category)
self.store.set_value(iter, 3, False)
self.modifiers[category][name]=val;
iter=self.store.append(self.modifiers[category]["iter"])
self.store.set_value(iter, 0, val.isOn())
self.store.set_value(iter, 1, self.translation.get_value(name))
self.store.set_value(iter, 2, name)
self.store.set_value(iter, 3, True)
def set(self,name,val):
category=self.translation.get_category(name)
self.modifiers[category][name].set(val)
if self.isBoolean(name):
self.booleanDirty=True
def isBoolean(self,name):
c=self.translation.get_category(name)
return isinstance(self.modifiers[c][name], Boolean)
def get_booleans(self):
booleans={}
for c in self.modifiers.keys():
for n in self.modifiers[c].keys():
if isinstance(self.modifiers[c][n], Boolean):
booleans[n]=self.modifiers[c][n]
return booleans
def save(self, boolconf):
if self.booleanDirty == True:
booleans=self.get_booleans()
setseboolS="/usr/sbin/setsebool -P "
for b in booleans.keys():
if booleans[b].save==1:
setseboolS += "%s=%d " % (b, booleans[b].isOn())
boolconf[b]=str(booleans[b].isOn())
commands.getstatusoutput(setseboolS)
class selinuxPage:
def __init__(self, xml, doDebug=None, inFirstboot=False):
self.xml = xml
self.selinuxsupport = True
self.translation = Translation()
self.typechanged = False
self.needRelabel = False
self.doDebug = doDebug
self.inFirstboot = inFirstboot
# Bring in widgets from glade file.
self.seLinuxVBox = xml.get_widget("seLinuxVBox")
self.typeHBox = xml.get_widget("typeHBox")
self.selinuxTypeOptionMenu = xml.get_widget("selinuxTypeOptionMenu")
self.tunableSW = xml.get_widget("tunableSW")
self.tunableView = xml.get_widget("tunableView")
self.typeLabel = xml.get_widget("typeLabel")
self.modifySeparator = xml.get_widget("modifySeparator")
self.enabledOptionMenu = xml.get_widget("enabledOptionMenu")
self.tunableExpander = xml.get_widget("tunableExpander")
listStore = gtk.ListStore(gobject.TYPE_STRING)
self.selinuxTypeOptionMenu.set_model(listStore)
cell = gtk.CellRendererText()
self.selinuxTypeOptionMenu.pack_start(cell, True)
self.selinuxTypeOptionMenu.add_attribute(cell, 'text', 0)
listStore = gtk.ListStore(gobject.TYPE_STRING)
self.enabledOptionMenu.set_model(listStore)
cell = gtk.CellRendererText()
self.enabledOptionMenu.pack_start(cell, True)
self.enabledOptionMenu.add_attribute(cell, 'text', 0)
self.enabledOptionMenu.append_text("Enforcing")
self.enabledOptionMenu.append_text("Permissive")
self.enabledOptionMenu.append_text("Disabled")
self.tunableStore = gtk.TreeStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
self.tunableStore.set_sort_column_id(1, gtk.SORT_ASCENDING)
self.tunableView.set_model(self.tunableStore)
checkbox = gtk.CellRendererToggle()
checkbox.connect("toggled", self.tunable_toggled)
col = gtk.TreeViewColumn('', checkbox, active = 0,visible=3)
col.set_fixed_width(20)
col.set_clickable(True)
self.tunableView.append_column(col)
col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=1)
self.tunableView.append_column(col)
if self.read_selinux_config() == None:
self.seLinuxVBox.set_sensitive(False)
self.selinuxsupport = False
else:
self.enabledOptionMenu.connect("changed", self.enabled_changed)
self.refreshTunables(self.initialtype)
#
# This line must come after read_selinux_config
#
self.selinuxTypeOptionMenu.connect("changed", self.typemenu_changed)
self.typeLabel.set_mnemonic_widget(self.selinuxTypeOptionMenu)
# This line should always go last
self.dirty = False
def setup_relabel(self):
fd=open(RELABELFILE,"w")
fd.close()
def get_current_mode(self):
return commands.getoutput("/usr/sbin/getenforce")
def set_current_mode(self,value):
return commands.getoutput("/usr/sbin/setenforce %d" % value)
def verify(self, message):
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
gtk.BUTTONS_YES_NO,
message)
dlg.set_position(gtk.WIN_POS_MOUSE)
dlg.show_all()
rc = dlg.run()
dlg.destroy()
return rc
def typemenu_changed(self, menu):
type = self.getType()
if self.initialtype != type:
self.dirty = True
if self.inFirstboot == False and self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO:
menu.set_active(self.typeHistory)
return None
self.needRelabel = True
else:
self.dirty = False
self.refreshTunables(type)
def loadBooleans(self):
booleansList=commands.getoutput("/usr/sbin/getsebool -a").split("\n")
for i in booleansList:
rec=i.split()
name=rec[0]
if rec[2]=="on" or rec[2]=="active":
on=1
else:
on=0
self.modifiers.add(name,Boolean(name,on))
def refreshTunables(self,type):
self.modifiers=Modifiers(self.tunableStore)
self.typeHistory=self.selinuxTypeOptionMenu.get_active()
# Load Bools
if type==self.initialtype:
self.loadBooleans()
def enabled_changed(self, combo):
setting = combo.get_active()
if setting < 2:
enabled = True
else:
enabled = False
# If the combo has been changed back to its inital setting, we don't
# need to do anything.
if setting == self.initEnabled:
self.dirty = False
self.needRelabel = False
else:
self.dirty = True
# If we were initially disabled, we must be set to enabling here.
if self.initEnabled == DISABLED:
if self.inFirstboot == False and self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO:
return None
self.needRelabel = True
else:
self.needRelabel = False
self.typeLabel.set_sensitive(enabled)
self.selinuxTypeOptionMenu.set_sensitive(enabled)
self.tunableExpander.set_sensitive(enabled)
def read_selinux_config(self):
self.initialtype="targeted"
self.initEnabled = DISABLED
self.boolconf={}
self.types=[]
if os.access(SELINUXDIR, os.F_OK) == 0:
#File doesn't exist. return
return None
self.conf=ConfShellVar(SELINUXDIR+"config")
self.conf.rcs=1
if self.conf.has_key("SELINUX"):
value=self.conf.vars["SELINUX"].upper().strip()
else:
value="ENFORCING"
self.conf.vars["SELINUX"]=value
if value == "ENFORCING":
self.initEnabled = ENFORCING
self.enabledOptionMenu.set_active(ENFORCING)
elif value == "PERMISSIVE":
self.initEnabled = PERMISSIVE
self.enabledOptionMenu.set_active(PERMISSIVE)
elif value == "DISABLED":
self.initEnabled = DISABLED
self.enabledOptionMenu.set_active(DISABLED)
self.enabled_changed(self.enabledOptionMenu)
if self.conf.has_key("SELINUXTYPE"):
self.initialtype=self.conf.vars["SELINUXTYPE"].strip()
else:
self.conf.vars["SELINUXTYPE"]=self.initialtype
n=0
current=n
for i in os.listdir(SELINUXDIR):
if os.path.isdir(SELINUXDIR+i) and os.path.isdir(SELINUXDIR+i+"/policy"):
self.types.append(i)
self.selinuxTypeOptionMenu.append_text(i)
if i == self.initialtype:
current=n
n=n+1
self.boolconf[i]=ConfShellVar(SELINUXDIR+self.initialtype+"/booleans")
self.boolconf[i].rcs=1
self.selinuxTypeOptionMenu.set_active(current)
# Only display the policy type selector if there's more than one
# to choose from.
if len(self.types) == 0:
self.seLinuxVBox.remove(self.typeHBox)
self.seLinuxVBox.remove(self.modifySeparator)
return None
elif len(self.types) == 1:
self.seLinuxVBox.remove(self.typeHBox)
self.seLinuxVBox.remove(self.modifySeparator)
return 0
def tunable_toggled(self, widget, row):
if len(row) == 1:
return
iter = self.tunableStore.get_iter(row)
val = self.tunableStore.get_value(iter, 0)
key = self.tunableStore.get_value(iter, 2)
self.tunableStore.set_value(iter, 0 , not val)
self.modifiers.set(key, not val)
def getType(self):
return self.types[self.selinuxTypeOptionMenu.get_active()]
def apply(self):
retval = 0
if self.selinuxsupport==False:
return retval
type=self.getType()
if self.dirty == True:
enabled = self.enabledOptionMenu.get_active()
if enabled == ENFORCING:
self.conf["SELINUX"] = "enforcing"
self.set_current_mode(1)
elif enabled == PERMISSIVE:
self.conf["SELINUX"] = "permissive"
self.set_current_mode(0)
elif enabled == DISABLED:
# The only way to make sure SELinux is disabled is to reboot.
# We should also setenforce 0 right now too.
self.conf["SELINUX"] = "disabled"
self.set_current_mode(0)
retval = 1
self.conf["SELINUXTYPE"]=type
if not self.doDebug:
self.conf.write()
if self.needRelabel:
if not self.doDebug:
self.setup_relabel()
retval = 1
else:
if os.access(RELABELFILE, os.F_OK) != 0 and not self.doDebug:
os.unlink(RELABELFILE)
if self.initialtype == type and self.modifiers.save(self.boolconf[type]) and not self.doDebug:
self.reloadPolicy()
return retval
def reloadPolicy(self):
dialog = gtk.MessageDialog (None,
gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
gtk.MESSAGE_WARNING,
gtk.BUTTONS_OK,
_("Reloading Policy. This may take a minute."))
dialog.set_position(gtk.WIN_POS_MOUSE)
dialog.show ()
dialog.get_toplevel().window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
while gtk.events_pending():
gtk.main_iteration()
command= "make -C %s/%s/src/policy reload" % (SELINUXDIR , self.getType())
status=commands.getstatusoutput(command)[0]
dialog.destroy ()
return status