use rrsync to restrict rsync access
[schsh.git] / schsh
diff --git a/schsh b/schsh
index b433a19ab1034af1c16ff8f36aea21fd7067ac2a..823eeaa70cfcf710311451f5ae610dfa0769d888 100755 (executable)
--- a/schsh
+++ b/schsh
@@ -1,33 +1,39 @@
-#!/usr/bin/python
+#!/usr/bin/python3
+import logging, logging.handlers
+import os, sys, shlex, pwd
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
 # Configuration
 shell = None # set to "/bin/bash" or similar to allow shell access
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
 # Configuration
 shell = None # set to "/bin/bash" or similar to allow shell access
+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):
+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 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
 
        return True
 
-def allowRSync(run):
+def allowRSync(run, runstr):
        if len(run) < 3: return False
        if run[0] != "rsync": return False
        if run[1] != "--server": return False
        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
 
        return True
 
-def allowSFTP(run):
-       if len(run) != 1: return False
-       return run[0] == "/usr/lib/openssh/sftp-server"
+def allowSFTP(run, runstr):
+       return runstr == "/usr/lib/openssh/sftp-server"
 
 allowCommands = [allowSCP, allowRSync, allowSFTP]
 
 allowCommands = [allowSCP, allowRSync, allowSFTP]
-commandPaths = ["/usr/bin", "/bin"]
 
 # END of Configuration
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
 # DO NOT TOUCH ANYTHING BELOW THIS LINE
 
 
 # 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)
 
 logger = logging.getLogger("schsh")
 logger.setLevel(logging.INFO)
@@ -44,38 +50,27 @@ def logquit(msg):
        log(msg, logging.ERROR)
        sys.exit(1)
 
        log(msg, logging.ERROR)
        sys.exit(1)
 
-def commandAllowed(run):
+def commandAllowed(run, runstr):
        for allowed in allowCommands:
        for allowed in allowCommands:
-               if allowed(run):
+               if allowed(run, runstr):
                        return True
        return False
 
                        return True
        return False
 
-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
-
 # parse arguments
 run = []
 if len(sys.argv) == 1:
        if shell is None:
 # 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])
                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 commandAllowed(run):
-               run[0] = addPath(run[0])
+       if commandAllowed(run, sys.argv[2]): # this may change run, but that's okay
                log("Running '"+str(run)+"'")
        else:
                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))
                logquit("Attempt to run invalid command '"+sys.argv[2]+"'")
 else:
        logquit("Invalid arguments for schsh: "+str(sys.argv))