diff --git a/pythonrewrite/bin/Makefile b/pythonrewrite/bin-perl-old/Makefile similarity index 100% rename from pythonrewrite/bin/Makefile rename to pythonrewrite/bin-perl-old/Makefile diff --git a/pythonrewrite/bin/cbox-manage.sh b/pythonrewrite/bin-perl-old/cbox-manage.sh similarity index 100% rename from pythonrewrite/bin/cbox-manage.sh rename to pythonrewrite/bin-perl-old/cbox-manage.sh diff --git a/pythonrewrite/bin/cbox-root-actions.sh b/pythonrewrite/bin-perl-old/cbox-root-actions.sh similarity index 100% rename from pythonrewrite/bin/cbox-root-actions.sh rename to pythonrewrite/bin-perl-old/cbox-root-actions.sh diff --git a/pythonrewrite/bin/cryptobox.pl b/pythonrewrite/bin-perl-old/cryptobox.pl similarity index 100% rename from pythonrewrite/bin/cryptobox.pl rename to pythonrewrite/bin-perl-old/cryptobox.pl diff --git a/pythonrewrite/bin/cryptobox_wrapper.c b/pythonrewrite/bin-perl-old/cryptobox_wrapper.c similarity index 100% rename from pythonrewrite/bin/cryptobox_wrapper.c rename to pythonrewrite/bin-perl-old/cryptobox_wrapper.c diff --git a/pythonrewrite/bin/ro-system.sh b/pythonrewrite/bin-perl-old/ro-system.sh similarity index 100% rename from pythonrewrite/bin/ro-system.sh rename to pythonrewrite/bin-perl-old/ro-system.sh diff --git a/pythonrewrite/bin2/CryptoBoxRootActions.py b/pythonrewrite/bin2/CryptoBoxRootActions.py index d727b0c..8a9aa59 100755 --- a/pythonrewrite/bin2/CryptoBoxRootActions.py +++ b/pythonrewrite/bin2/CryptoBoxRootActions.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2.4 + """module for executing the programs, that need root privileges Syntax: @@ -28,13 +29,67 @@ allowedProgs = { 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): """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 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 - the effective uid (not the real uid)""" + the effective uid (not the real uid) + """ # first check, if the device/file exists if not os.path.exists(device): return False @@ -221,7 +276,7 @@ if __name__ == "__main__": sys.exit(100) # 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) if os.getuid() == 0: @@ -229,17 +284,29 @@ if __name__ == "__main__": sys.exit(100) # 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 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 - if len(sys.argv) < 2: - sys.stderr.write("Not enough arguments supplied (%s)!\n" % " ".join(sys.argv)) + if len(args) < 2: + sys.stderr.write("Not enough arguments supplied (%s)!\n" % " ".join(args)) sys.exit(100) - progRequest = sys.argv[0] - del sys.argv[0] + progRequest = args[0] + del args[0] if not progRequest in allowedProgs.keys(): 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.exit(100) try: - if runner(sys.argv): + if runner(args): sys.exit(0) else: sys.exit(1) diff --git a/pythonrewrite/plugins/date/date.py b/pythonrewrite/plugins/date/date.py index 59b1a91..5f70e0b 100644 --- a/pythonrewrite/plugins/date/date.py +++ b/pythonrewrite/plugins/date/date.py @@ -1,4 +1,6 @@ from CryptoBoxExceptions import CBPluginActionError +import subprocess +import os 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) except ValueError: raise CBPluginActionError, "InvalidDate" - # TODO: how to set the current time? (and how to become root?) - ## we will continue with the system menue - return "form_system" + 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"), + "%02d%02d%02d%02d%d" % (month, day, hour, minute, year)]) + proc.communicate() + if proc.returncode == 0: + return "form_system" + else: + raise CBPluginActionError, "InvalidDate" else: return "form_date" diff --git a/pythonrewrite/plugins/date/root_action.py b/pythonrewrite/plugins/date/root_action.py new file mode 100755 index 0000000..d0c2f0d --- /dev/null +++ b/pythonrewrite/plugins/date/root_action.py @@ -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) + diff --git a/pythonrewrite/plugins/logs/lang/en.hdf b/pythonrewrite/plugins/logs/lang/en.hdf index af85d64..cc74717 100644 --- a/pythonrewrite/plugins/logs/lang/en.hdf +++ b/pythonrewrite/plugins/logs/lang/en.hdf @@ -6,7 +6,7 @@ Lang { Modules.logs { Name = Show the content of the log file - Link = Show the log file + Link = Show log file Rank = 90 } diff --git a/pythonrewrite/plugins/network/lang/en.hdf b/pythonrewrite/plugins/network/lang/en.hdf index 7e1861d..5c1cac8 100644 --- a/pythonrewrite/plugins/network/lang/en.hdf +++ b/pythonrewrite/plugins/network/lang/en.hdf @@ -12,7 +12,7 @@ Lang { Rank = 30 } - Warning.InvalidIP { + WarningMessage.InvalidIP { Title = Invalid value Text = An invalid network address (IP) was supplied. Please try again. } diff --git a/pythonrewrite/plugins/network/network.py b/pythonrewrite/plugins/network/network.py index 04529dd..67652da 100644 --- a/pythonrewrite/plugins/network/network.py +++ b/pythonrewrite/plugins/network/network.py @@ -1,8 +1,12 @@ from CryptoBoxExceptions import CBPluginActionError +import re +import subprocess +import imp +import os 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.oc2"] = oc2 hdf["Data.Modules.network.ip.oc3"] = oc3 @@ -12,22 +16,51 @@ def prepareForm(hdf, cbox): def doAction(cbox, store=None, ip1="", ip2="", ip3="", ip4=""): if store: try: - # TODO: check the IP here - pass + for ip_in in (ip1, ip2, ip3, ip4): + 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: raise CBPluginActionError, "InvalidIP" - # TODO: how to set the new IP? (and how to become root?) - ## we will continue with the system menue - return "form_system" + if __setIP(cbox, ip): + return "form_system" + else: + raise CBPluginActionError, "InvalidIP" else: return "form_network" def getStatus(cbox): - return "%d.%d.%d.%d" % __getCurrentIP() + return "%d.%d.%d.%d" % __getCurrentIP(cbox) -def __getCurrentIP(): - # TODO: for now we only provide a dummy - return (192,168,0,23) +def __getCurrentIP(cbox): + root_action_mod = imp.load_source("root_action", os.path.join(os.path.dirname(__file__), "root_action.py")) + 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 diff --git a/pythonrewrite/plugins/network/root_action.py b/pythonrewrite/plugins/network/root_action.py new file mode 100755 index 0000000..1ec7ae8 --- /dev/null +++ b/pythonrewrite/plugins/network/root_action.py @@ -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) +