src/hg-ssh
changeset 106 0519745e7a57
parent 103 ae1845978e38
child 107 84e9e33d866b
equal deleted inserted replaced
105:cd3da73cdf63 106:0519745e7a57
    31 # enable importing on demand to reduce startup time
    31 # enable importing on demand to reduce startup time
    32 from mercurial import demandimport; demandimport.enable()
    32 from mercurial import demandimport; demandimport.enable()
    33 
    33 
    34 from mercurial import dispatch
    34 from mercurial import dispatch
    35 
    35 
    36 import sys, os
    36 import sys, os, os.path
    37 from mercurialserver import ruleset, paths
    37 from mercurialserver import ruleset, paths
    38 
    38 
    39 def fail(message):
    39 def fail(message):
    40     #logfile.write("Fail: %s\n" % message)
    40     sys.stderr.write("mercurial-server: %s\n" % message)
    41     sys.stderr.write(message + "\n")
       
    42     sys.exit(-1)
    41     sys.exit(-1)
    43 
    42 
    44 def getpath(path):
    43 def checkpath(path)
    45     path = path.rstrip("/")
    44     path = os.path.dirname(path)
    46     if not ruleset.goodpath(path):
    45     if path == "":
    47         fail("Disallowing path: %s" % path)
    46         return
    48     return path
    47     if os.path.exists(path + "/.hg"):
       
    48         raise ruleset.AccessException()
       
    49     checkpath(path)
    49 
    50 
    50 def try_cmd(cmd):
    51 def getrepo(op, repo):
    51     if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
    52     repo = os.path.normcase(os.path.normpath(repo.rstrip("/")))
    52         repo = getpath(cmd[6:-14])
    53     if len(repo) == 0:
    53         ruleset.rules.set(repo=repo)
    54         fail("path to repository seems to be empty")
    54         if ruleset.rules.allow("read", branch=None, file=None):
    55     if repo.startswith("/"):
    55             dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
    56         fail("absolute paths are not supported")
    56             return
    57     for component in repo.split("/"):
    57     elif cmd.startswith('hg init '):
    58         if component.startswith("."):
    58         repo = getpath(cmd[8:])
    59             fail("paths cannot contain dot file components")
    59         ruleset.rules.set(repo=repo)
    60     ruleset.rules.set(repo=repo)
    60         if ruleset.rules.allow("init", branch=None, file=None):
    61     ruleset.rules.check(op, branch=None, file=None)
    61             dispatch.dispatch(['init', repo])
    62     checkpath(repo)
    62             return
    63     return repo
    63     fail("Illegal command %r" % cmd)
       
    64 
    64 
    65 #logfile = open("/tmp/hg-ssh.%d.txt" % os.getpid(), "w")
    65 #logfile = open("/tmp/hg-ssh.%d.txt" % os.getpid(), "w")
    66 #logfile.write("Started: %s\n" % sys.argv)
    66 #logfile.write("Started: %s\n" % sys.argv)
    67 
    67 
    68 if len(sys.argv) != 2:
    68 if len(sys.argv) != 2:
    69     fail("hg-ssh must have exactly one argument (%s)" 
    69     fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" 
    70         % sys.argv)
    70         % sys.argv)
    71 
    71 
    72 paths.setExePath()
    72 paths.setExePath()
    73 ruleset.rules.set(user = sys.argv[1])
    73 ruleset.rules.set(user = sys.argv[1])
    74 
    74 
    83     paths.getEtcPath() + "/access.conf", 
    83     paths.getEtcPath() + "/access.conf", 
    84     os.getcwd() + "/hgadmin/access.conf"]:
    84     os.getcwd() + "/hgadmin/access.conf"]:
    85     if os.path.isfile(f):
    85     if os.path.isfile(f):
    86         ruleset.rules.readfile(f)
    86         ruleset.rules.readfile(f)
    87 
    87 
    88 try_cmd(os.environ.get('SSH_ORIGINAL_COMMAND', '?'))
    88 cmd = os.environ.get('SSH_ORIGINAL_COMMAND', '')
       
    89 try:
       
    90     if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
       
    91         repo = getrepo("read", cmd[6:-14])
       
    92         if not os.path.isdir(repo + "/.hg")
       
    93             fail("no such repository %s" % repo)
       
    94         dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
       
    95     elif cmd.startswith('hg init '):
       
    96         repo = getrepo("init", cmd[8:])
       
    97         if os.path.exists(repo):
       
    98             fail("%s exists" % repo)
       
    99         d = os.path.dirname(repo)
       
   100         if d != "" and not os.path.isdir(d):
       
   101             os.makedirs(d)
       
   102         dispatch.dispatch(['init', repo])
       
   103     elif cmd == "":
       
   104         fail("direct logins on the hg account prohibited ")
       
   105     else:
       
   106         fail("illegal command %r" % cmd)
       
   107 except ruleset.AccessException:
       
   108     fail("access denied")
       
   109