2023-12-06 14:31:51 +00:00
|
|
|
#!/usr/bin/python3 -EsI
|
2013-10-11 14:16:57 +00:00
|
|
|
|
|
|
|
import dbus
|
|
|
|
import dbus.service
|
2021-07-28 16:59:22 +00:00
|
|
|
from dbus.mainloop.glib import DBusGMainLoop
|
2016-11-12 20:20:21 +00:00
|
|
|
from gi.repository import GObject
|
2021-07-28 16:59:22 +00:00
|
|
|
from gi.repository import GLib
|
2013-10-11 14:16:57 +00:00
|
|
|
import os
|
|
|
|
import selinux
|
|
|
|
from subprocess import Popen, PIPE, STDOUT
|
|
|
|
|
2015-07-24 08:07:13 +00:00
|
|
|
|
2021-07-28 16:58:35 +00:00
|
|
|
class selinux_server(dbus.service.Object):
|
2013-10-11 14:16:57 +00:00
|
|
|
default_polkit_auth_required = "org.selinux.semanage"
|
2015-07-24 08:07:13 +00:00
|
|
|
|
|
|
|
def __init__(self, *p, **k):
|
2013-10-11 14:16:57 +00:00
|
|
|
super(selinux_server, self).__init__(*p, **k)
|
|
|
|
|
2021-07-28 16:58:35 +00:00
|
|
|
def is_authorized(self, sender, action_id):
|
|
|
|
bus = dbus.SystemBus()
|
|
|
|
proxy = bus.get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
|
|
|
|
authority = dbus.Interface(proxy, dbus_interface='org.freedesktop.PolicyKit1.Authority')
|
|
|
|
subject = ('system-bus-name', {'name': sender})
|
|
|
|
result = authority.CheckAuthorization(subject, action_id, {}, 1, '')
|
|
|
|
return result[0]
|
|
|
|
|
2013-10-11 14:16:57 +00:00
|
|
|
#
|
|
|
|
# The semanage method runs a transaction on a series of semanage commands,
|
2019-08-05 20:11:20 +00:00
|
|
|
# these commands can take the output of customized
|
2013-10-11 14:16:57 +00:00
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender")
|
|
|
|
def semanage(self, buf, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.semanage"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
dbus: Use text streams in selinux_server.py
subprocess.Popen called without universal_newlines=True opens stdin,
stout and stderr as binary stream which cause problems with Python 3.
Fixes:
Traceback (most recent call last):
File "/usr/lib64/python3.4/site-packages/sepolicy/gui.py", line 2773, in unconfined_toggle
self.dbus.semanage("module -e unconfined")
File "<string>", line 2, in semanage
File "/usr/lib/python3.4/site-packages/slip/dbus/polkit.py", line 121, in _enable_proxy
return func(*p, **k)
File "/usr/lib64/python3.4/site-packages/sepolicy/sedbus.py", line 14, in semanage
ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
File "/usr/lib64/python3.4/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python3.4/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Python.TypeError: TypeError: 'dbus.String' does not support the buffer interface
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2017-05-03 10:30:32 +00:00
|
|
|
p = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=True)
|
2013-10-11 14:16:57 +00:00
|
|
|
p.stdin.write(buf)
|
|
|
|
output = p.communicate()
|
|
|
|
if p.returncode and p.returncode != 0:
|
|
|
|
raise dbus.exceptions.DBusException(output[1])
|
|
|
|
|
|
|
|
#
|
|
|
|
# The customized method will return all of the custommizations for policy
|
|
|
|
# on the server. This output can be used with the semanage method on
|
|
|
|
# another server to make the two systems have duplicate policy.
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='', out_signature='s', sender_keyword="sender")
|
|
|
|
def customized(self, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.customized"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
dbus: Use text streams in selinux_server.py
subprocess.Popen called without universal_newlines=True opens stdin,
stout and stderr as binary stream which cause problems with Python 3.
Fixes:
Traceback (most recent call last):
File "/usr/lib64/python3.4/site-packages/sepolicy/gui.py", line 2773, in unconfined_toggle
self.dbus.semanage("module -e unconfined")
File "<string>", line 2, in semanage
File "/usr/lib/python3.4/site-packages/slip/dbus/polkit.py", line 121, in _enable_proxy
return func(*p, **k)
File "/usr/lib64/python3.4/site-packages/sepolicy/sedbus.py", line 14, in semanage
ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
File "/usr/lib64/python3.4/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python3.4/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Python.TypeError: TypeError: 'dbus.String' does not support the buffer interface
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2017-05-03 10:30:32 +00:00
|
|
|
p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
2013-10-11 14:16:57 +00:00
|
|
|
buf = p.stdout.read()
|
|
|
|
output = p.communicate()
|
|
|
|
if p.returncode and p.returncode != 0:
|
|
|
|
raise OSError("Failed to read SELinux configuration: %s", output)
|
|
|
|
return buf
|
|
|
|
|
|
|
|
#
|
2017-05-03 10:30:27 +00:00
|
|
|
# The semodule_list method will return the output of semodule --list=full, using the customized polkit,
|
2013-10-11 14:16:57 +00:00
|
|
|
# since this is a readonly behaviour
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='', out_signature='s', sender_keyword="sender")
|
|
|
|
def semodule_list(self, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.semodule_list"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
dbus: Use text streams in selinux_server.py
subprocess.Popen called without universal_newlines=True opens stdin,
stout and stderr as binary stream which cause problems with Python 3.
Fixes:
Traceback (most recent call last):
File "/usr/lib64/python3.4/site-packages/sepolicy/gui.py", line 2773, in unconfined_toggle
self.dbus.semanage("module -e unconfined")
File "<string>", line 2, in semanage
File "/usr/lib/python3.4/site-packages/slip/dbus/polkit.py", line 121, in _enable_proxy
return func(*p, **k)
File "/usr/lib64/python3.4/site-packages/sepolicy/sedbus.py", line 14, in semanage
ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
File "/usr/lib64/python3.4/site-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib64/python3.4/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Python.TypeError: TypeError: 'dbus.String' does not support the buffer interface
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2017-05-03 10:30:32 +00:00
|
|
|
p = Popen(["/usr/sbin/semodule", "--list=full"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
2013-10-11 14:16:57 +00:00
|
|
|
buf = p.stdout.read()
|
|
|
|
output = p.communicate()
|
|
|
|
if p.returncode and p.returncode != 0:
|
|
|
|
raise OSError("Failed to list SELinux modules: %s", output)
|
|
|
|
return buf
|
|
|
|
|
|
|
|
#
|
|
|
|
# The restorecon method modifies any file path to the default system label
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender")
|
|
|
|
def restorecon(self, path, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.restorecon"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
2013-10-11 14:16:57 +00:00
|
|
|
selinux.restorecon(str(path), recursive=1)
|
|
|
|
|
|
|
|
#
|
|
|
|
# The setenforce method turns off the current enforcement of SELinux
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='i', sender_keyword="sender")
|
|
|
|
def setenforce(self, value, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.setenforce"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
2013-10-11 14:16:57 +00:00
|
|
|
selinux.security_setenforce(value)
|
|
|
|
|
|
|
|
#
|
|
|
|
# The setenforce method turns off the current enforcement of SELinux
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='i', sender_keyword="sender")
|
|
|
|
def relabel_on_boot(self, value, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.relabel_on_boot"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
2013-10-11 14:16:57 +00:00
|
|
|
if value == 1:
|
2015-07-24 08:07:13 +00:00
|
|
|
fd = open("/.autorelabel", "w")
|
2013-10-11 14:16:57 +00:00
|
|
|
fd.close()
|
|
|
|
else:
|
2019-11-15 14:54:25 +00:00
|
|
|
try:
|
|
|
|
os.unlink("/.autorelabel")
|
|
|
|
except FileNotFoundError:
|
|
|
|
pass
|
2013-10-11 14:16:57 +00:00
|
|
|
|
|
|
|
def write_selinux_config(self, enforcing=None, policy=None):
|
|
|
|
path = selinux.selinux_path() + "config"
|
|
|
|
backup_path = path + ".bck"
|
|
|
|
fd = open(path)
|
|
|
|
lines = fd.readlines()
|
|
|
|
fd.close()
|
|
|
|
fd = open(backup_path, "w")
|
|
|
|
for l in lines:
|
|
|
|
if enforcing and l.startswith("SELINUX="):
|
|
|
|
fd.write("SELINUX=%s\n" % enforcing)
|
|
|
|
continue
|
|
|
|
if policy and l.startswith("SELINUXTYPE="):
|
|
|
|
fd.write("SELINUXTYPE=%s\n" % policy)
|
|
|
|
continue
|
|
|
|
fd.write(l)
|
|
|
|
fd.close()
|
|
|
|
os.rename(backup_path, path)
|
|
|
|
|
|
|
|
#
|
|
|
|
# The change_default_enforcement modifies the current enforcement mode
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender")
|
|
|
|
def change_default_mode(self, value, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.change_default_mode"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
2015-07-24 08:07:13 +00:00
|
|
|
values = ["enforcing", "permissive", "disabled"]
|
2013-10-11 14:16:57 +00:00
|
|
|
if value not in values:
|
|
|
|
raise ValueError("Enforcement mode must be %s" % ", ".join(values))
|
|
|
|
self.write_selinux_config(enforcing=value)
|
|
|
|
|
|
|
|
#
|
|
|
|
# The change_default_policy method modifies the policy type
|
|
|
|
#
|
2021-07-28 16:58:35 +00:00
|
|
|
@dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender")
|
|
|
|
def change_default_policy(self, value, sender):
|
|
|
|
if not self.is_authorized(sender, "org.selinux.change_default_policy"):
|
|
|
|
raise dbus.exceptions.DBusException("Not authorized")
|
2013-10-11 14:16:57 +00:00
|
|
|
path = selinux.selinux_path() + value
|
|
|
|
if os.path.isdir(path):
|
|
|
|
return self.write_selinux_config(policy=value)
|
|
|
|
raise ValueError("%s does not exist" % path)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2021-07-28 16:59:22 +00:00
|
|
|
DBusGMainLoop(set_as_default=True)
|
|
|
|
mainloop = GLib.MainLoop()
|
|
|
|
|
2015-07-24 08:07:13 +00:00
|
|
|
system_bus = dbus.SystemBus()
|
|
|
|
name = dbus.service.BusName("org.selinux", system_bus)
|
2021-07-28 16:59:22 +00:00
|
|
|
server = selinux_server(system_bus, "/org/selinux/object")
|
2015-07-24 08:07:13 +00:00
|
|
|
mainloop.run()
|