X-Git-Url: https://git.ralfj.de/schsh.git/blobdiff_plain/807db80a3e637f5a8e7083a79e174827ae2339d1..HEAD:/schsh diff --git a/schsh b/schsh index 270691e..1a790bb 100755 --- a/schsh +++ b/schsh @@ -1,16 +1,39 @@ -#!/usr/bin/python +#!/usr/bin/env python3 +import logging, logging.handlers +import os, sys, shlex, pwd #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Configuration shell = None # set to "/bin/bash" or similar to allow shell access -allowCommands = ["scp", "rsync", "/usr/lib/openssh/sftp-server"] -commandPaths = ["/usr/bin", "/bin"] +rrsync = "/usr/local/bin/schsh-rrsync" # path to the restricted rsync script - if available, it will be used to further restrict rsync access + +def allowSCP(run, runstr): + if len(run) != 3: return False + if run[0] != "scp": return False + if run[1] not in ("-f", "-t"): return False + if run[2].startswith('-'): return False + run[0] = "/usr/bin/scp" + return True + +def allowRSync(run, runstr): + if len(run) < 3: return False + if run[0] != "rsync": return False + if run[1] != "--server": return False + if rrsync is None: + # rrsync is not available, let's hope this is enough protection + run[0] = "/usr/bin/rsync" + return True + run[:] = [rrsync, "/", runstr] # allow access to the entire chroot + return True + +def allowSFTP(run, runstr): + return runstr == "/usr/lib/openssh/sftp-server" + +allowCommands = [allowSCP, allowRSync, allowSFTP] # END of Configuration #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # DO NOT TOUCH ANYTHING BELOW THIS LINE -import logging, logging.handlers -import os, sys, shlex, pwd logger = logging.getLogger("schsh") logger.setLevel(logging.INFO) @@ -27,35 +50,30 @@ def logquit(msg): log(msg, logging.ERROR) sys.exit(1) -def addPath(prog): - if prog.startswith("/"): - return prog - # look for it in the paths - for path in commandPaths: - fullprog = os.path.join(path, prog) - if os.path.exists(fullprog): - return fullprog - return None +def commandAllowed(run, runstr): + for allowed in allowCommands: + if allowed(run, runstr): + return True + return False # parse arguments run = [] if len(sys.argv) == 1: if shell is None: - print "No shell for you!" + print("No shell for you!") logquit("Shell access not allowed") else: run = [shell] elif len(sys.argv) == 3 and sys.argv[1] == "-c": # check if the command is allowed, and add path run = shlex.split(sys.argv[2]) - if len(run) > 0 and run[0] in allowCommands: - run[0] = addPath(run[0]) - log("Running '"+str(run)+"'") + if commandAllowed(run, sys.argv[2]): # this may change run, but that's okay + log("Running "+str(run)) else: - print "You are not allowed to run this command." + print("You are not allowed to run this command.") logquit("Attempt to run invalid command '"+sys.argv[2]+"'") else: logquit("Invalid arguments for schsh: "+str(sys.argv)) assert len(run) > 0 -os.execl("/usr/bin/schroot", "/usr/bin/schroot", "-c", "user-"+get_username(), "-d", "/data", "--", *run) +os.execl("/usr/bin/schroot", "/usr/bin/schroot", "-c", "schsh-"+get_username(), "-d", "/data", "--", *run)