implemented root actions for plugins

finished network and date plugins
renamed old 'bin' direcory
This commit is contained in:
lars 2006-09-13 10:38:05 +00:00
parent 2b4180a83b
commit e80b8874ff
13 changed files with 211 additions and 23 deletions

View file

@ -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)