Simple Python scp wrapper
Inspired by the following article I decided to write a simply python scp wrapper which is based on the ideas taken from the perl script also mentioned on the same page.
The whole point of this wrapper is dead simple: to allow certain users scp into their specific directories with out granting full ssh access.
The configuration file is straightforward:
/opt/etc/scponly.conf
scponly=/tmp:/home/scptest
Below is the wrapper in all its amature (must admit I’m not a developer at all) glory ;-)
/opt/bin/scp-wrapper.py:
#!/usr/bin/python import sys import os import pwd from subprocess import call, Popen, PIPE import re def fail(msg): """(str) -> str Prints error message to STDOUT >>> fail('Error') Error >>> fail('Wrong argument') Wrong argument """ print msg sys.exit(1) def access_verify(user, dirto): """(str) -> Boolean Returns TRUE iff user is allowed to scp """ if user in users: for d in users[user]: print user, dirto[-1:], d.rstrip()[-1:], dirto[:-1] == d.rstrip(), dirto == d[:-1].rstrip() if dirto == d.rstrip(): return True elif (dirto[-1:] == "/" or d.rstrip()[-1:] == "/") and (dirto[:-1] == d.rstrip() or dirto == d.rstrip()[:-1]): return True else: return False return False if __name__ == '__main__': users = {} conf = "/usr/local/etc/scponly.conf" # Reading configuration file fp = open(conf, "r") for line in fp.readlines(): record = line.split("=") users[record[0]] = record[1].split(":") fp.close() command = sys.argv[2] scp_args = command.split() if scp_args[0] != "scp": msg = "Only scp is allowed" fail(msg) if scp_args[1] != "-t" and not "-f" and not "-v": msg = "Restricted; only server mode is allowed" fail(msg) destdir = scp_args[-1] if not os.path.isfile(destdir) or os.path.isfile(destdir): destdirv = os.path.dirname(destdir) else: destdirv = destdir uname = pwd.getpwuid(os.getuid())[0] if not access_verify(uname, destdirv): msg = "User " + uname + " is not authorized to scp to this host." fail(msg) else: scp_args.pop(0) if len(scp_args) == 2: call(["/usr/bin/scp", scp_args[0], destdir]) elif len(scp_args) == 3: call(["/usr/bin/scp", scp_args[0], scp_args[1], destdir])
Just create a new user and set its shell (-s option in useradd) to /opt/bin/scp-wrapper.py. Hope it helps.
Enjoy and have fun!