hg-ssh
changeset 33 18e93dbdaf12
parent 32 4059dbe9f26a
child 34 4b5ca59fe3b7
equal deleted inserted replaced
32:4059dbe9f26a 33:18e93dbdaf12
     1 #!/usr/bin/env python
       
     2 #
       
     3 # Copyright 2008 LShift Ltd
       
     4 # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
       
     5 # Authors:
       
     6 # Paul Crowley <paul@lshift.net>
       
     7 # Thomas Arendsen Hein <thomas@intevation.de>
       
     8 # with ideas from  Mathieu PASQUET <kiorky@cryptelium.net>
       
     9 #
       
    10 # This software may be used and distributed according to the terms
       
    11 # of the GNU General Public License, incorporated herein by reference.
       
    12 
       
    13 """
       
    14 hg-ssh - limit access to hg repositories reached via ssh.  Part of
       
    15 hg-admin-tools.
       
    16 
       
    17 This script is called by hg-ssh-wrapper with no arguments - everything
       
    18 should be in enviroment variables:
       
    19 
       
    20 HG_ACCESS_RULES_FILE identifies the path to the rules file
       
    21 REMOTE_USER the remote user (which is the key used by ssh)
       
    22 SSH_ORIGINAL_COMMAND the command the user was trying to run
       
    23 
       
    24 It uses SSH_ORIGINAL_COMMAND to determine what the user was trying to
       
    25 do and to what repository, and then checks each rule in the rule file
       
    26 in turn for a matching rule which decides what to do, defaulting to
       
    27 disallowing the action.
       
    28 
       
    29 """
       
    30 
       
    31 # enable importing on demand to reduce startup time
       
    32 from mercurial import demandimport; demandimport.enable()
       
    33 
       
    34 from mercurial import dispatch
       
    35 
       
    36 import sys, os
       
    37 import ruleset
       
    38 
       
    39 def fail(message):
       
    40     #logfile.write("Fail: %s\n" % message)
       
    41     sys.stderr.write(message + "\n")
       
    42     sys.exit(-1)
       
    43 
       
    44 def getpath(path):
       
    45     if path.endswith("/"):
       
    46         path = path[:-1]
       
    47     if not ruleset.goodpath(path):
       
    48         fail("Disallowing path: %s" % path)
       
    49     return path
       
    50 
       
    51 def get_cmd(rules, cmd):
       
    52     if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
       
    53         repo = getpath(cmd[6:-14])
       
    54         if rules.allow("read", repo=repo):
       
    55             os.environ["HG_REPO_PATH"] = repo
       
    56             return ['-R', repo, 'serve', '--stdio']
       
    57     elif cmd.startswith('hg init '):
       
    58         repo = getpath(cmd[8:])
       
    59         if rules.allow("init", repo=repo):
       
    60             os.environ["HG_REPO_PATH"] = repo
       
    61             return ['init', repo]
       
    62     fail("Illegal command %r" % cmd)
       
    63 
       
    64 #logfile = open("/tmp/hg-ssh.%d.txt" % os.getpid(), "w")
       
    65 #logfile.write("Started: %s\n" % sys.argv)
       
    66 
       
    67 if len(sys.argv) != 1:
       
    68     fail("hg-ssh must have no arguments (%s)" 
       
    69         % sys.argv)
       
    70 
       
    71 rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
       
    72 rules.set(user = getpath(os.environ['REMOTE_USER']))
       
    73 rules.set(branch = None, file = None)
       
    74 todispatch = get_cmd(rules, 
       
    75     os.environ.get('SSH_ORIGINAL_COMMAND', '?'))
       
    76 dispatch.dispatch(todispatch)
       
    77