1#!/usr/bin/python 2 3import dbus 4import dbus.service 5import dbus.mainloop.glib 6import gobject 7import slip.dbus.service 8from slip.dbus import polkit 9import os 10import selinux 11from subprocess import Popen, PIPE, STDOUT 12 13class selinux_server(slip.dbus.service.Object): 14 default_polkit_auth_required = "org.selinux.semanage" 15 def __init__ (self, *p, **k): 16 super(selinux_server, self).__init__(*p, **k) 17 18 # 19 # The semanage method runs a transaction on a series of semanage commands, 20 # these commnds can take the output of customized 21 # 22 @slip.dbus.polkit.require_auth("org.selinux.semanage") 23 @dbus.service.method("org.selinux", in_signature='s') 24 def semanage(self, buf): 25 p = Popen(["/usr/sbin/semanage", "import"],stdout=PIPE, stderr=PIPE, stdin=PIPE) 26 p.stdin.write(buf) 27 output = p.communicate() 28 if p.returncode and p.returncode != 0: 29 raise dbus.exceptions.DBusException(output[1]) 30 31 # 32 # The customized method will return all of the custommizations for policy 33 # on the server. This output can be used with the semanage method on 34 # another server to make the two systems have duplicate policy. 35 # 36 @slip.dbus.polkit.require_auth("org.selinux.customized") 37 @dbus.service.method("org.selinux", in_signature='', out_signature='s') 38 def customized(self): 39 p = Popen(["/usr/sbin/semanage", "export"],stdout=PIPE, stderr=PIPE) 40 buf = p.stdout.read() 41 output = p.communicate() 42 if p.returncode and p.returncode != 0: 43 raise OSError("Failed to read SELinux configuration: %s", output) 44 return buf 45 46 # 47 # The semodule_list method will return the output of semodule -l, using the customized polkit, 48 # since this is a readonly behaviour 49 # 50 @slip.dbus.polkit.require_auth("org.selinux.semodule_list") 51 @dbus.service.method("org.selinux", in_signature='', out_signature='s') 52 def semodule_list(self): 53 p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE) 54 buf = p.stdout.read() 55 output = p.communicate() 56 if p.returncode and p.returncode != 0: 57 raise OSError("Failed to list SELinux modules: %s", output) 58 return buf 59 60 # 61 # The restorecon method modifies any file path to the default system label 62 # 63 @slip.dbus.polkit.require_auth("org.selinux.restorecon") 64 @dbus.service.method("org.selinux", in_signature='s') 65 def restorecon(self, path): 66 selinux.restorecon(str(path), recursive=1) 67 68 # 69 # The setenforce method turns off the current enforcement of SELinux 70 # 71 @slip.dbus.polkit.require_auth("org.selinux.setenforce") 72 @dbus.service.method("org.selinux", in_signature='i') 73 def setenforce(self, value): 74 selinux.security_setenforce(value) 75 76 # 77 # The setenforce method turns off the current enforcement of SELinux 78 # 79 @slip.dbus.polkit.require_auth("org.selinux.relabel_on_boot") 80 @dbus.service.method("org.selinux", in_signature='i') 81 def relabel_on_boot(self, value): 82 if value == 1: 83 fd = open("/.autorelabel","w") 84 fd.close() 85 else: 86 os.unlink("/.autorelabel") 87 88 def write_selinux_config(self, enforcing=None, policy=None): 89 path = selinux.selinux_path() + "config" 90 backup_path = path + ".bck" 91 fd = open(path) 92 lines = fd.readlines() 93 fd.close() 94 fd = open(backup_path, "w") 95 for l in lines: 96 if enforcing and l.startswith("SELINUX="): 97 fd.write("SELINUX=%s\n" % enforcing) 98 continue 99 if policy and l.startswith("SELINUXTYPE="): 100 fd.write("SELINUXTYPE=%s\n" % policy) 101 continue 102 fd.write(l) 103 fd.close() 104 os.rename(backup_path, path) 105 106 # 107 # The change_default_enforcement modifies the current enforcement mode 108 # 109 @slip.dbus.polkit.require_auth("org.selinux.change_default_mode") 110 @dbus.service.method("org.selinux", in_signature='s') 111 def change_default_mode(self, value): 112 values = [ "enforcing", "permissive", "disabled" ] 113 if value not in values: 114 raise ValueError("Enforcement mode must be %s" % ", ".join(values)) 115 self.write_selinux_config(enforcing=value) 116 117 118 # 119 # The change_default_policy method modifies the policy type 120 # 121 @slip.dbus.polkit.require_auth("org.selinux.change_default_policy") 122 @dbus.service.method("org.selinux", in_signature='s') 123 def change_default_policy(self, value): 124 path = selinux.selinux_path() + value 125 if os.path.isdir(path): 126 return self.write_selinux_config(policy=value) 127 raise ValueError("%s does not exist" % path) 128 129if __name__ == "__main__": 130 mainloop = gobject.MainLoop() 131 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 132 system_bus = dbus.SystemBus() 133 name = dbus.service.BusName("org.selinux", system_bus) 134 object = selinux_server(system_bus, "/org/selinux/object") 135 slip.dbus.service.set_mainloop(mainloop) 136 mainloop.run() 137