implemented root actions for plugins
finished network and date plugins renamed old 'bin' direcory
This commit is contained in:
parent
2b4180a83b
commit
e80b8874ff
13 changed files with 211 additions and 23 deletions
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env python2.4
|
#!/usr/bin/env python2.4
|
||||||
|
|
||||||
"""module for executing the programs, that need root privileges
|
"""module for executing the programs, that need root privileges
|
||||||
|
|
||||||
Syntax:
|
Syntax:
|
||||||
|
@ -28,13 +29,67 @@ allowedProgs = {
|
||||||
DEV_TYPES = { "pipe":1, "char":2, "dir":4, "block":6, "file":8, "link":10, "socket":12}
|
DEV_TYPES = { "pipe":1, "char":2, "dir":4, "block":6, "file":8, "link":10, "socket":12}
|
||||||
|
|
||||||
|
|
||||||
|
def checkIfPluginIsSafe(plugin):
|
||||||
|
"""check if the plugin and its parents are only writeable for root"""
|
||||||
|
#FIXME: for now we may skip this test - but users will not like it this way :)
|
||||||
|
return True
|
||||||
|
props = os.stat(plugin)
|
||||||
|
## check if it is owned by non-root
|
||||||
|
if props.st_uid != 0: return False
|
||||||
|
## check group-write permission if gid is not zero
|
||||||
|
if (props.st_gid != 0) and (props.st_mode % 32 / 16 > 0): return False
|
||||||
|
## check if it is world-writeable
|
||||||
|
if props.st_mode % 4 / 2 > 0: return False
|
||||||
|
## are we at root-level (directory-wise)? If yes, then we are ok ...
|
||||||
|
if plugin == os.path.sep: return True
|
||||||
|
## check if the parent directory is ok - recursively :)
|
||||||
|
return checkIfPluginIsSafe(os.path.dirname(os.path.abspath(plugin)))
|
||||||
|
|
||||||
|
|
||||||
|
def checkIfPluginIsValid(plugin):
|
||||||
|
import imp
|
||||||
|
try:
|
||||||
|
x = imp.load_source("cbox_plugin",plugin)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
if getattr(x, "PLUGIN_TYPE") == "cryptobox":
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def call_plugin(args):
|
||||||
|
"""check if the plugin may be called - and do it finally ..."""
|
||||||
|
plugin = os.path.abspath(args[0])
|
||||||
|
del args[0]
|
||||||
|
## check existence and excutability
|
||||||
|
if not os.access(plugin, os.X_OK):
|
||||||
|
raise Exception, "could not find executable plugin (%s)" % plugin
|
||||||
|
## check if the plugin (and its parents) are only writeable for root
|
||||||
|
if not checkIfPluginIsSafe(plugin):
|
||||||
|
raise Exception, "the plugin (%s) was not safe - check its (and its parents') permissions" % plugin
|
||||||
|
## check if the plugin is a python program, that is marked as a cryptobox plugin
|
||||||
|
if not checkIfPluginIsValid(plugin):
|
||||||
|
raise Exception, "the plugin (%s) is not a correctly marked python script" % plugin
|
||||||
|
args.insert(0,plugin)
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = args)
|
||||||
|
proc.communicate()
|
||||||
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
def isWriteable(device, force_dev_type=None):
|
def isWriteable(device, force_dev_type=None):
|
||||||
"""check if the calling user (not root!) has write access to the device/file
|
"""check if the calling user (not root!) has write access to the device/file
|
||||||
|
|
||||||
the real (not the effictive) user id is used for the check
|
the real (not the effictive) user id is used for the check
|
||||||
additionally the permissions of the default groups of the real uid are checked
|
additionally the permissions of the default groups of the real uid are checked
|
||||||
this check works nicely together with "super", as it changes (by default) only
|
this check works nicely together with "super", as it changes (by default) only
|
||||||
the effective uid (not the real uid)"""
|
the effective uid (not the real uid)
|
||||||
|
"""
|
||||||
# first check, if the device/file exists
|
# first check, if the device/file exists
|
||||||
if not os.path.exists(device):
|
if not os.path.exists(device):
|
||||||
return False
|
return False
|
||||||
|
@ -221,7 +276,7 @@ if __name__ == "__main__":
|
||||||
sys.exit(100)
|
sys.exit(100)
|
||||||
|
|
||||||
# remove program name
|
# remove program name
|
||||||
sys.argv.remove(sys.argv[0])
|
args = sys.argv[1:]
|
||||||
|
|
||||||
# do not allow to use root permissions (real uid may not be zero)
|
# do not allow to use root permissions (real uid may not be zero)
|
||||||
if os.getuid() == 0:
|
if os.getuid() == 0:
|
||||||
|
@ -229,17 +284,29 @@ if __name__ == "__main__":
|
||||||
sys.exit(100)
|
sys.exit(100)
|
||||||
|
|
||||||
# did the user call the "check" action?
|
# did the user call the "check" action?
|
||||||
if (len(sys.argv) == 1) and (sys.argv[0].lower() == "check"):
|
if (len(args) == 1) and (args[0].lower() == "check"):
|
||||||
# exit silently
|
# exit silently
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args[0].lower() == "plugin":
|
||||||
|
del args[0]
|
||||||
|
try:
|
||||||
|
isOK = call_plugin(args)
|
||||||
|
except Exception, errMsg:
|
||||||
|
sys.stderr.write("Execution of plugin failed: %s\n" % errMsg)
|
||||||
|
sys.exit(100)
|
||||||
|
if isOK:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# check parameters count
|
# check parameters count
|
||||||
if len(sys.argv) < 2:
|
if len(args) < 2:
|
||||||
sys.stderr.write("Not enough arguments supplied (%s)!\n" % " ".join(sys.argv))
|
sys.stderr.write("Not enough arguments supplied (%s)!\n" % " ".join(args))
|
||||||
sys.exit(100)
|
sys.exit(100)
|
||||||
|
|
||||||
progRequest = sys.argv[0]
|
progRequest = args[0]
|
||||||
del sys.argv[0]
|
del args[0]
|
||||||
|
|
||||||
if not progRequest in allowedProgs.keys():
|
if not progRequest in allowedProgs.keys():
|
||||||
sys.stderr.write("Invalid program requested: %s\n" % progRequest)
|
sys.stderr.write("Invalid program requested: %s\n" % progRequest)
|
||||||
|
@ -253,7 +320,7 @@ if __name__ == "__main__":
|
||||||
sys.stderr.write("The interface for this program (%s) is not yet implemented!\n" % progRequest)
|
sys.stderr.write("The interface for this program (%s) is not yet implemented!\n" % progRequest)
|
||||||
sys.exit(100)
|
sys.exit(100)
|
||||||
try:
|
try:
|
||||||
if runner(sys.argv):
|
if runner(args):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
else:
|
else:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from CryptoBoxExceptions import CBPluginActionError
|
from CryptoBoxExceptions import CBPluginActionError
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def prepareForm(hdf, cbox):
|
def prepareForm(hdf, cbox):
|
||||||
|
@ -19,9 +21,19 @@ def doAction(cbox, store=None, year=0, month=0, day=0, hour=0, minute=0):
|
||||||
new_date = datetime.datetime(year, month, day, hour, minute)
|
new_date = datetime.datetime(year, month, day, hour, minute)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CBPluginActionError, "InvalidDate"
|
raise CBPluginActionError, "InvalidDate"
|
||||||
# TODO: how to set the current time? (and how to become root?)
|
proc = subprocess.Popen(
|
||||||
## we will continue with the system menue
|
shell = False,
|
||||||
|
args = [
|
||||||
|
cbox.prefs["Programs"]["super"],
|
||||||
|
cbox.prefs["Programs"]["CryptoBoxRootActions"],
|
||||||
|
"plugin",
|
||||||
|
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
||||||
|
"%02d%02d%02d%02d%d" % (month, day, hour, minute, year)])
|
||||||
|
proc.communicate()
|
||||||
|
if proc.returncode == 0:
|
||||||
return "form_system"
|
return "form_system"
|
||||||
|
else:
|
||||||
|
raise CBPluginActionError, "InvalidDate"
|
||||||
else:
|
else:
|
||||||
return "form_date"
|
return "form_date"
|
||||||
|
|
||||||
|
|
35
pythonrewrite/plugins/date/root_action.py
Executable file
35
pythonrewrite/plugins/date/root_action.py
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/env python2.4
|
||||||
|
|
||||||
|
## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script
|
||||||
|
PLUGIN_TYPE = "cryptobox"
|
||||||
|
|
||||||
|
DATE_BIN = "/bin/date"
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = sys.argv[1:]
|
||||||
|
|
||||||
|
self_bin = sys.argv[0]
|
||||||
|
|
||||||
|
if len(args) > 1:
|
||||||
|
sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if re.search(u'\D', args[0]):
|
||||||
|
sys.stderr.write("%s: illegal argument (%s)\n" % (self_bin, args[0]))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [DATE_BIN, args[0]])
|
||||||
|
proc.communicate()
|
||||||
|
sys.exit(proc.returncode)
|
||||||
|
|
|
@ -6,7 +6,7 @@ Lang {
|
||||||
|
|
||||||
Modules.logs {
|
Modules.logs {
|
||||||
Name = Show the content of the log file
|
Name = Show the content of the log file
|
||||||
Link = Show the log file
|
Link = Show log file
|
||||||
Rank = 90
|
Rank = 90
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ Lang {
|
||||||
Rank = 30
|
Rank = 30
|
||||||
}
|
}
|
||||||
|
|
||||||
Warning.InvalidIP {
|
WarningMessage.InvalidIP {
|
||||||
Title = Invalid value
|
Title = Invalid value
|
||||||
Text = An invalid network address (IP) was supplied. Please try again.
|
Text = An invalid network address (IP) was supplied. Please try again.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
from CryptoBoxExceptions import CBPluginActionError
|
from CryptoBoxExceptions import CBPluginActionError
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import imp
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def prepareForm(hdf, cbox):
|
def prepareForm(hdf, cbox):
|
||||||
(oc1, oc2, oc3, oc4) = __getCurrentIP()
|
(oc1, oc2, oc3, oc4) = __getCurrentIP(cbox)
|
||||||
hdf["Data.Modules.network.ip.oc1"] = oc1
|
hdf["Data.Modules.network.ip.oc1"] = oc1
|
||||||
hdf["Data.Modules.network.ip.oc2"] = oc2
|
hdf["Data.Modules.network.ip.oc2"] = oc2
|
||||||
hdf["Data.Modules.network.ip.oc3"] = oc3
|
hdf["Data.Modules.network.ip.oc3"] = oc3
|
||||||
|
@ -12,22 +16,51 @@ def prepareForm(hdf, cbox):
|
||||||
def doAction(cbox, store=None, ip1="", ip2="", ip3="", ip4=""):
|
def doAction(cbox, store=None, ip1="", ip2="", ip3="", ip4=""):
|
||||||
if store:
|
if store:
|
||||||
try:
|
try:
|
||||||
# TODO: check the IP here
|
for ip_in in (ip1, ip2, ip3, ip4):
|
||||||
pass
|
if (int(ip_in) < 0) or (int(ip_in) > 255):
|
||||||
|
cbox.log.debug("invalid IP supplied: %s" % str((ip1,ip2,ip3,ip4)))
|
||||||
|
raise ValueError
|
||||||
|
ip = "%d.%d.%d.%d" % (int(ip1), int(ip2), int(ip3), int(ip4))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CBPluginActionError, "InvalidIP"
|
raise CBPluginActionError, "InvalidIP"
|
||||||
# TODO: how to set the new IP? (and how to become root?)
|
if __setIP(cbox, ip):
|
||||||
## we will continue with the system menue
|
|
||||||
return "form_system"
|
return "form_system"
|
||||||
|
else:
|
||||||
|
raise CBPluginActionError, "InvalidIP"
|
||||||
else:
|
else:
|
||||||
return "form_network"
|
return "form_network"
|
||||||
|
|
||||||
|
|
||||||
def getStatus(cbox):
|
def getStatus(cbox):
|
||||||
return "%d.%d.%d.%d" % __getCurrentIP()
|
return "%d.%d.%d.%d" % __getCurrentIP(cbox)
|
||||||
|
|
||||||
|
|
||||||
def __getCurrentIP():
|
def __getCurrentIP(cbox):
|
||||||
# TODO: for now we only provide a dummy
|
root_action_mod = imp.load_source("root_action", os.path.join(os.path.dirname(__file__), "root_action.py"))
|
||||||
return (192,168,0,23)
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
stdout = subprocess.PIPE,
|
||||||
|
args = [
|
||||||
|
root_action_mod.IFCONFIG_BIN,
|
||||||
|
root_action_mod.IFACE])
|
||||||
|
(output, error) = proc.communicate()
|
||||||
|
if proc.returncode != 0: return (0,0,0,0)
|
||||||
|
match = re.search(u'inet [\w]+:(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\s',output)
|
||||||
|
if match:
|
||||||
|
return tuple([int(e) for e in match.groups()])
|
||||||
|
else:
|
||||||
|
return (0,0,0,0)
|
||||||
|
|
||||||
|
|
||||||
|
def __setIP(cbox, ip):
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [
|
||||||
|
cbox.prefs["Programs"]["super"],
|
||||||
|
cbox.prefs["Programs"]["CryptoBoxRootActions"],
|
||||||
|
"plugin",
|
||||||
|
os.path.join(os.path.dirname(__file__), "root_action.py"),
|
||||||
|
ip])
|
||||||
|
proc.communicate()
|
||||||
|
return proc.returncode == 0
|
||||||
|
|
||||||
|
|
41
pythonrewrite/plugins/network/root_action.py
Executable file
41
pythonrewrite/plugins/network/root_action.py
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env python2.4
|
||||||
|
|
||||||
|
#TODO: add netmask and gateway
|
||||||
|
|
||||||
|
## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script
|
||||||
|
PLUGIN_TYPE = "cryptobox"
|
||||||
|
|
||||||
|
IFCONFIG_BIN = "/sbin/ifconfig"
|
||||||
|
IFACE = "eth0"
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = sys.argv[1:]
|
||||||
|
|
||||||
|
self_bin =sys.argv[0]
|
||||||
|
|
||||||
|
if len(args) > 1:
|
||||||
|
sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
sys.stderr.write("%s: no argument supplied\n" % self_bin)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
match = re.search(u'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$', args[0])
|
||||||
|
## did we match? If yes, then: are there wrong values inside?
|
||||||
|
if not match or [e for e in match.groups() if int(e) > 255]:
|
||||||
|
sys.stderr.write("%s: illegal argument (%s)\n" % (self_bin, args[0]))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
shell = False,
|
||||||
|
args = [IFCONFIG_BIN, IFACE, args[0]])
|
||||||
|
proc.communicate()
|
||||||
|
sys.exit(proc.returncode)
|
||||||
|
|
Loading…
Reference in a new issue