Merge in changes from upstream debian
authorPaul Crowley <paul@lshift.net>
Sat, 19 Dec 2009 19:21:41 +0000
branchdebian
changeset 248 107d28ce67f5
parent 240 97a8fe72a35e (current diff)
parent 247 efb4044593ed (diff)
child 249 c7aca8658582
Merge in changes from upstream
.hgtags
--- a/.hgtags	Fri Dec 18 13:25:45 2009 +0000
+++ b/.hgtags	Sat Dec 19 19:21:41 2009 +0000
@@ -6,4 +6,6 @@
 1e4050abb96e72c6324b93709e56a3e135e63ce1 debian_0.8-1
 d42d3f5311c55cab668d6962a61d44ba98645e release_0.9
 b6887a9b8792bb2b69b428448102140fce121e29 debian_0.9-1
+8ce190faa5c2b50f63cc5b11e28daf98836498d8 release_1.0
 60c2d676a754e02f1f7656a4b137399438b2ed35 debian_1.0-1
+92cb6640a6417edaf52870c8a97000e11bb8b138 release_1.0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CREDITS	Sat Dec 19 19:21:41 2009 +0000
@@ -0,0 +1,22 @@
+mercurial-server is by Paul Crowley <paul@lshift.net>
+
+Thanks to:
+
+Thomas Arendsen Hein <thomas@intevation.de>
+Mathieu PASQUET <kiorky@cryptelium.net>
+Vadim Gelfer <vadim.gelfer@gmail.com>
+Hubert Plociniczak <hubert@lshift.net>
+Christoph Junghans <kleiner_otti@gmx.de>
+Steve Kemp <steve@steve.org.uk>
+Cédric Boutillier <cedric.boutillier@gmail.com>
+Justin B Rye <jbr@edlug.org.uk>
+Wolfgang Karall <office@karall-edv.at>
+Helge Kreutzmann <debian@helgefjell.de>
+"Hideki Yamane \(Debian-JP\)" <henrich@debian.or.jp>
+Michal Simunek <michal.simunek@gmail.com>
+Martin Bagge <brother@bsnet.se>
+Vincenzo Campanella <vinz65@gmail.com>
+Ji ZhengYu <zhengyuji@gmail.com>
+
+This credits file may be incomplete - please remind me about people I
+should add!
--- a/NEWS	Fri Dec 18 13:25:45 2009 +0000
+++ b/NEWS	Sat Dec 19 19:21:41 2009 +0000
@@ -1,3 +1,17 @@
+======================
+mercurial-server 1.0.1
+======================
+
+* Fix HGRCPATH brokenness - potential security issue
+* Fix rule matching to properly handle the case where we don't know for sure
+* Fix error in documentation
+* Remove whitespace around paths, said to help with TortoiseHG
+* Small refactor of access.py
+* Tidy up file prologues; move credits to CREDITS
+
+Upgrading: repositories whose paths begin or end in white space will no longer
+be accessible; if they exist they must be moved to new names.
+
 ====================
 mercurial-server 1.0
 ====================
--- a/doc/manual.docbook	Fri Dec 18 13:25:45 2009 +0000
+++ b/doc/manual.docbook	Sat Dec 19 19:21:41 2009 +0000
@@ -147,7 +147,7 @@
 class='directory'>keys/users</filename>.  To grant this key access, we must give mercurial-server a new access rule, so we create a file in <filename
 class='directory'>hgadmin</filename> called <filename>access.conf</filename>, with the following contents:</para>
 <programlisting># Give Pat access to the "widget" repository
-write repo=widget user=pat
+write repo=widget user=pat/*
 </programlisting>
 <para>
 Pat will have read and write access to the <filename
--- a/setup.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/setup.py	Sat Dec 19 19:21:41 2009 +0000
@@ -7,7 +7,7 @@
     name="mercurial-server",
     description="Centralized Mercurial repository manager",
     url="http://www.lshift.net/mercurial-server.html",
-    version="0.9", # FIXME: infer this
+    version="1.0.1", # FIXME: infer this
     package_dir = {'': 'src'},
     packages = ["mercurialserver"],
     requires = ["mercurial"], # FIXME: what version?
--- a/src/hg-ssh	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/hg-ssh	Sat Dec 19 19:21:41 2009 +0000
@@ -1,14 +1,4 @@
 #!/usr/bin/env python
-#
-# Copyright 2008-2009 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
@@ -55,7 +45,7 @@
 def getrepo(op, repo):
     # First canonicalise, then check the string, then the rules
     # and finally the filesystem.
-    repo = repo.rstrip("/")
+    repo = repo.strip().rstrip("/")
     if len(repo) == 0:
         fail("path to repository seems to be empty")
     if repo.startswith("/"):
@@ -69,6 +59,9 @@
 
 config.initExe()
 
+for k,v in config.getEnv():
+    os.environ[k.upper()] = v
+
 if len(sys.argv) == 3 and sys.argv[1] == "--base64":
     ruleset.rules.set(user = base64.b64decode(sys.argv[2]))
 elif len(sys.argv) == 2:
@@ -77,9 +70,6 @@
     fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" 
         % sys.argv)
 
-for k,v in config.getEnv():
-    os.environ[k] = v
-
 os.chdir(config.getReposPath())
 
 for f in config.getAccessPaths():
--- a/src/mercurialserver/access.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/access.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,12 +1,4 @@
-# Copyright 2008-2009 LShift Ltd
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# Authors:
-# Paul Crowley <paul@lshift.net>
-# Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
+"""Mercurial access control hook"""
 
 from mercurial.i18n import _
 import mercurial.util
@@ -16,32 +8,21 @@
 from mercurialserver import ruleset
 from mercurialserver import changes
 
-class Checker(object):
-    '''acl checker.'''
-
-    def __init__(self, ui, repo):
-        self.ui = ui
-        self.repo = repo
-        
-    def allow(self, ctx):
-        branch = ctx.branch()
-        if not ruleset.rules.allow("write", branch=branch, file=None):
+def allow(ctx):
+    branch = ctx.branch()
+    if not ruleset.rules.allow("write", branch=branch, file=None):
+        return False
+    for f in ctx.files():
+        if not ruleset.rules.allow("write", branch=branch, file=f):
             return False
-        for f in ctx.files():
-            if not ruleset.rules.allow("write", branch=branch, file=f):
-                return False
-        return True
-
-    def check(self, ctx):
-        '''return if access allowed, raise exception if not.'''
-        if not self.allow(ctx):
-            raise mercurial.util.Abort(_('%s: access denied for changeset %s') %
-                (__name__, mercurial.node.short(ctx.node())))
+    return True
 
 def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
     if hooktype != 'pretxnchangegroup':
         raise mercurial.util.Abort(_('config error - hook type "%s" cannot stop '
                            'incoming changesets') % hooktype)
-    c = Checker(ui, repo)
     for ctx in changes.changes(repo, node):
-        c.check(ctx)
+        if not allow(ctx):
+            raise mercurial.util.Abort(_('%s: access denied for changeset %s') %
+                (__name__, mercurial.node.short(ctx.node())))
+
--- a/src/mercurialserver/changes.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/changes.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,12 +1,6 @@
-# Copyright 2008-2009 LShift Ltd
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# Authors:
-# Paul Crowley <paul@lshift.net>
-# Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
+"""
+Find all the changes in a node in a way portable across Mercurial versions
+"""
 
 def changes(repo, node):
     start = repo.changectx(node).rev()
--- a/src/mercurialserver/config.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/config.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,4 +1,6 @@
-# Copyright 2008-2009 LShift Ltd
+"""
+Fix $HOME and read ~/.mercurial-server
+"""
 
 import sys
 import os
--- a/src/mercurialserver/refreshauth.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/refreshauth.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,9 +1,6 @@
-# Copyright 2008-2009 LShift Ltd
-
-# WARNING
-# This hook completely destroys your ~/.ssh/authorized_keys
-# file every time it is run
-# WARNING
+"""
+Rewrite ~/.ssh/authorized_keys by recursing through key directories
+"""
 
 import re
 import base64
--- a/src/mercurialserver/ruleset.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/ruleset.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,29 +1,31 @@
-# Copyright 2008-2009 LShift Ltd
-# Author(s):
-# Paul Crowley <paul@lshift.net>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
+"""
+Glob-based, order-based rules matcher that can answer "maybe"
+where the inputs make clear that something is unknown.
+"""
 
 import sys
 import re
 import os
 import os.path
 
-allowedchars = "A-Za-z0-9_-"
-
 def globmatcher(pattern):
     p = "[^/]*".join(re.escape(c) for c in pattern.split("*"))
     # ** means "match recursively" ie "ignore directories"
-    rex = re.compile(p.replace("[^/]*[^/]*", ".*") + "$")
-    # None matches everything
-    return lambda x: x is None or rex.match(x) is not None
+    return re.compile(p.replace("[^/]*[^/]*", ".*") + "$")
 
+# Returns True for a definite match
+# False for a definite non-match
+# None where we can't be sure because a key is None
 def rule(pairs):
     matchers = [(k, globmatcher(v)) for k, v in pairs]
     def c(kw):
         for k, m in matchers:
-            if k not in kw or not m(kw[k]):
+            if k not in kw:
+                return False
+            kkw = kw[k]
+            if kkw is None:
+                return None
+            if m.match(kkw) is None:
                 return False
         return True
     return c
@@ -46,32 +48,39 @@
     def get(self, k):
         return self.preset.get(k, None)
         
-    def matchrule(self, kw):
+    def matchrules(self, kw):
         d = self.preset.copy()
         d.update(kw)
+        res = set()
         for a, c in self.rules:
-            if c(d):
-                return a
-        return None
+            m = c(d)
+            if m is None:
+                # "Maybe match" - add it and carry on
+                res.add(a)
+            elif m:
+                # Definite match - add it and stop
+                res.add(a)
+                break
+        return res
 
     def allow(self, level, **kw):
-        a = self.matchrule(kw)
-        return a in self.levels and self.levels.index(a) <= self.levels.index(level)
+        for a in self.matchrules(kw):
+            if a in self.levels:
+                if self.levels.index(a) <= self.levels.index(level):
+                    return True
+        return False
     
     def readfile(self, fn):
+        f = open(fn)
         try:
-            f = open(fn)
-            try:
-                for l in f:
-                    l = l.strip()
-                    if len(l) == 0 or l.startswith("#"):
-                        continue
-                    l = l.split()
-                    self.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
-            finally:
-                f.close()
-        except Exception, e:
-            print >> sys.stderr, "Failure reading rules file:", e
+            for l in f:
+                l = l.strip()
+                if len(l) == 0 or l.startswith("#"):
+                    continue
+                l = l.split()
+                self.add(l[0], rule([c.split("=", 1) for c in l[1:]]))
+        finally:
+            f.close()
 
 rules = Ruleset()
 
--- a/src/mercurialserver/servelog.py	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/mercurialserver/servelog.py	Sat Dec 19 19:21:41 2009 +0000
@@ -1,10 +1,6 @@
-# Copyright 2008-2009 LShift Ltd
-#
-# Authors:
-# Paul Crowley <paul@lshift.net>
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
+"""
+Hook to log changesets pushed and pulled
+"""
 
 from mercurial.i18n import _
 import mercurial.util
--- a/src/refresh-auth	Fri Dec 18 13:25:45 2009 +0000
+++ b/src/refresh-auth	Sat Dec 19 19:21:41 2009 +0000
@@ -1,10 +1,7 @@
 #!/usr/bin/env python
-# Copyright 2008-2009 LShift Ltd
-
-# WARNING
-# This script completely destroys your ~/.ssh/authorized_keys
-# file every time it is run
-# WARNING
+"""
+Rewrite ~/.ssh/authorized_keys by recursing through key directories
+"""
 
 import sys
 import os