src/hg-ssh
changeset 33 18e93dbdaf12
parent 25 9d78dca32325
child 36 b3237aabd0fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hg-ssh	Mon Jun 16 17:12:20 2008 +0100
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 LShift Ltd
+# Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
+# Authors:
+# Paul Crowley <paul@lshift.net>
+# Thomas Arendsen Hein <thomas@intevation.de>
+# with ideas from  Mathieu PASQUET <kiorky@cryptelium.net>
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+"""
+hg-ssh - limit access to hg repositories reached via ssh.  Part of
+hg-admin-tools.
+
+This script is called by hg-ssh-wrapper with no arguments - everything
+should be in enviroment variables:
+
+HG_ACCESS_RULES_FILE identifies the path to the rules file
+REMOTE_USER the remote user (which is the key used by ssh)
+SSH_ORIGINAL_COMMAND the command the user was trying to run
+
+It uses SSH_ORIGINAL_COMMAND to determine what the user was trying to
+do and to what repository, and then checks each rule in the rule file
+in turn for a matching rule which decides what to do, defaulting to
+disallowing the action.
+
+"""
+
+# enable importing on demand to reduce startup time
+from mercurial import demandimport; demandimport.enable()
+
+from mercurial import dispatch
+
+import sys, os
+import ruleset
+
+def fail(message):
+    #logfile.write("Fail: %s\n" % message)
+    sys.stderr.write(message + "\n")
+    sys.exit(-1)
+
+def getpath(path):
+    if path.endswith("/"):
+        path = path[:-1]
+    if not ruleset.goodpath(path):
+        fail("Disallowing path: %s" % path)
+    return path
+
+def get_cmd(rules, cmd):
+    if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
+        repo = getpath(cmd[6:-14])
+        if rules.allow("read", repo=repo):
+            os.environ["HG_REPO_PATH"] = repo
+            return ['-R', repo, 'serve', '--stdio']
+    elif cmd.startswith('hg init '):
+        repo = getpath(cmd[8:])
+        if rules.allow("init", repo=repo):
+            os.environ["HG_REPO_PATH"] = repo
+            return ['init', repo]
+    fail("Illegal command %r" % cmd)
+
+#logfile = open("/tmp/hg-ssh.%d.txt" % os.getpid(), "w")
+#logfile.write("Started: %s\n" % sys.argv)
+
+if len(sys.argv) != 1:
+    fail("hg-ssh must have no arguments (%s)" 
+        % sys.argv)
+
+rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
+rules.set(user = getpath(os.environ['REMOTE_USER']))
+rules.set(branch = None, file = None)
+todispatch = get_cmd(rules, 
+    os.environ.get('SSH_ORIGINAL_COMMAND', '?'))
+dispatch.dispatch(todispatch)
+