Mercurial > hg > pyhgsh
view contrib/pyhgsh/pyhgsh @ 2425:eee271568e8a default tip
Initial version of pyhgsh
author | Josef "Jeff" Sipek <jeffpc@optonline.net> |
---|---|
date | Sun, 18 Jun 2006 16:48:38 -0400 |
parents | |
children |
line wrap: on
line source
#!/usr/bin/python # # pyhgsh - restricted login shell for mercurial implemented in Python # # Copyright 2006 Josef "Jeff" Sipek <jsipek@cs.sunysb.edu> # # This software may be used and distributed according to the terms of the # GNU General Public License, incorporated herein by reference. # # this program is login shell for dedicated mercurial user account. it # only allows few actions: # # 1. run hg in server mode on specific repository. # # 2. run interactive shell, allows for repository maintainance # # only tested on linux yet. patches for non-linux systems welcome. # import os import sys name = "pyhgsh" version = "0.5" prompt = "> " repofile= "pyhgsh.repos" repos = [] def debugexit(argv, code): print argv sys.exit(0) def write(str): sys.stdout.write(str) def valid_repo(r): " returns true if r is in list of repos" global repos for okr in repos: if okr == r: return True return False def cmd_help(args): print name + ": The Python Mercurial shell" print "" print "available commands:" print "" for c in cmds: print " %s\t%s" % (c[0], c[2]) def cmd_verify(args): try: repo = args[0] except IndexError: print name + ": you must specify a valid repository" return if not valid_repo(repo): print name + ": '%s' is not a valid repository" % (repo,) return os.system("hg -R %s verify" % (repo,)) def cmd_repos(args): for r in repos: print r def cmd_quit(args): sys.exit(0) def cmd_version(args): print name + " (version " + version + ")" os.system("hg version | head -1") def cmd_invalid(cmd): print name + ": Invalid command '%s'" % (cmd,) def interactive(): """ This is an interactive shell handler """ print "" cmd_help([]) print "" while True: write(prompt) try: line = sys.stdin.readline() tok = line.strip().split(" ") except KeyboardInterrupt: # ctrl-c print "" continue if len(line) == 0: # ctrl-d ? print "" cmd_quit([]) if tok[0] != "": # non-empty command ok = False for c in cmds: if tok[0] == c[0]: # command found, execute c[1](tok[1:]) ok = True break if not ok: # command not found cmd_invalid(tok[0]) def execute(cmd): """ Request for execution of a command handler """ # this is the potentially exploitable area of the shell therefore we # must make sure that everything is checked properly before we # execute the command tok = cmd.split(" ") # it must be a hg call if tok[0] != "hg": print "Not a hg call" return # FIXME: hacky if cmd.find(";") != -1: print "Detected attept to exploit shell" return # FIXME: make sure the repo is allowed os.system(cmd) def main(argv): """ main, get things prepared """ argv.pop(0) # read in list of allowed repositories global repos f = open(repofile) repos = f.readlines() f.close() for i in range(len(repos)): repos[i] = repos[i].strip() if len(argv) == 0: # no args interactive() elif len(argv) == 2: if argv[0] == "-c": # execute command execute(argv[1]) else: # unknown debugexit(argv, 1) else: # unkown debugexit(argv, 1) # commented out commands are not implemented cmds = ( # ("clone", cmd_clone, "clone a repository"), ("help", cmd_help, "this screen help"), # ("init", cmd_init, "init a repository"), # ("pull", cmd_pull, "pull changes from one repository to another"), # ("push", cmd_push, "push changes from one repository to another"), ("quit", cmd_quit, "close this session"), ("repos", cmd_repos, "list repositories available"), ("verify", cmd_verify, "verify a repository"), ("version", cmd_version, "display version"), ) if __name__ == "__main__": main(sys.argv)