# HG changeset patch # User Paul Crowley # Date 1259776120 0 # Node ID 3a28047ec6dc07b431e515b5c159d7e53097932b # Parent f98f716b2ae89ed75d5a10be0400359db3c27858# Parent 8ce190faa5c2b50f63cc5b11e28daf98836498d8 Merge in new upstream version diff -r f98f716b2ae8 -r 3a28047ec6dc .hgtags --- a/.hgtags Wed Dec 02 17:46:28 2009 +0000 +++ b/.hgtags Wed Dec 02 17:48:40 2009 +0000 @@ -4,4 +4,5 @@ 95c9ab8e4bfc6fea6460b3147c3097373eba5d42 debian_0.7 1ad9d5841a48a77f68dc5350bd1f941327a6348a release_0.8 1e4050abb96e72c6324b93709e56a3e135e63ce1 debian_0.8-1 +d42d3f5311c55cab668d6962a61d44ba98645e release_0.9 b6887a9b8792bb2b69b428448102140fce121e29 debian_0.9-1 diff -r f98f716b2ae8 -r 3a28047ec6dc Makefile --- a/Makefile Wed Dec 02 17:46:28 2009 +0000 +++ b/Makefile Wed Dec 02 17:48:40 2009 +0000 @@ -5,6 +5,7 @@ DOCDIR=$(PREFIX)/doc/mercurial-server ETCDIR=/etc/mercurial-server NEWUSER=hg +DOCBOOK_XSL=/usr/share/xml/docbook/stylesheet/nwalsh INSTALL=install @@ -18,7 +19,11 @@ installetc: $(INSTALL) -d $(DESTDIR)$(ETCDIR) $(INSTALL) -m 644 -t $(DESTDIR)$(ETCDIR) \ - src/init/conf/remote-hgrc src/init/conf/access.conf + src/init/conf/access.conf + $(INSTALL) -d $(DESTDIR)$(ETCDIR)/remote-hgrc.d + $(INSTALL) -m 644 -t $(DESTDIR)$(ETCDIR)/remote-hgrc.d \ + src/init/conf/remote-hgrc.d/access.rc \ + src/init/conf/remote-hgrc.d/logging.rc $(INSTALL) -d $(DESTDIR)$(ETCDIR)/keys/root $(INSTALL) -d $(DESTDIR)$(ETCDIR)/keys/users @@ -29,11 +34,11 @@ $(INSTALL) -m 644 -t $(DESTDIR)$(DOCDIR)/html build/html/index.html build/html/index.html: doc/manual.docbook - xsltproc --nonet -o $@ /usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl $^ + xsltproc --nonet -o $@ $(DOCBOOK_XSL)/html/docbook.xsl $^ build/pdf/manual.pdf: doc/manual.docbook mkdir -p build/pdf - fop -xml $^ -xsl /usr/share/xml/docbook/stylesheet/nwalsh/fo/docbook.xsl $@ + fop -xml $^ -xsl $(DOCBOOK_XSL)/fo/docbook.xsl $@ pythonbuild: python setup.py build diff -r f98f716b2ae8 -r 3a28047ec6dc NEWS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NEWS Wed Dec 02 17:48:40 2009 +0000 @@ -0,0 +1,63 @@ +==================== +mercurial-server 1.0 +==================== + +* Add "env" section to .mercurial-server instead of special-casing HGRCPATH +* Switch to remote-hgrc.d directory instead of single file. +* Control path of authorized keys file in .mercurial_server +* Overwrite $HOME with value from /etc/passwd +* Use Python's ConfigParser instead of too-new mercurial.config +* Fix very out-of-date comments in hg-ssh +* Belatedly added NEWS file :-) + +Upgrading: move the paths/hgrc entry in .mercurial-server to env/HGRCPATH, +and add an entry under paths that reads +"authorized_keys = ~/.ssh/authorized_keys" + +==================== +mercurial-server 0.9 +==================== + +* Switch to supporting DESTDIR prefix in Makefile for easier packaging + +==================== +mercurial-server 0.8 +==================== + +* Remove .deb-specific stuff in Docbook documentation - let the README + handle that stuff. Also fixes bad version numbers in there. +* Move html docs into subdirectory +* Line wrap README + +==================== +mercurial-server 0.7 +==================== + +* Introduce .mercurial-server file for hg user +* Remove all restrictions on paths, except for dotfiles in repo paths +* Automatically create containing dirs for subdir repos +* Guard against repos in repos +* Switch to Makefile/setup.py based installer +* Switch to Docbook based documentation +* Load purge extension for hgadmin repo +* Guard against setting up hg user who already has .ssh/authorized_keys +* Link to real home page + +Upgrading: you'll need to create a .mercurial-server file +for the hg user - a suitable one is in the init directory. + +==================== +mercurial-server 0.6 +==================== + +* Remove hardcoding of init file path in hginit +* Switch from /usr/lib to /usr/share +* Install documentation +* Don't create "hg" user if install root is not root. + +==================== +mercurial-server 0.5 +==================== + +* First numbered release + diff -r f98f716b2ae8 -r 3a28047ec6dc doc/manual.docbook --- a/doc/manual.docbook Wed Dec 02 17:46:28 2009 +0000 +++ b/doc/manual.docbook Wed Dec 02 17:48:40 2009 +0000 @@ -311,10 +311,10 @@ class='directory'>hgadmin. -/etc/mercurial-server/remote-hgrc is in the +/etc/mercurial-server/remote-hgrc.d is in the HGRCPATH for all remote access to mercurial-server -repositories. This file contains the hooks that mercurial-server uses for -access control and logging. You can add hooks to this file, but obviously +repositories. This directory contains the hooks that mercurial-server uses for +access control and logging. You can add hooks to this directory, but obviously breaking the existing hooks will disable the relevant functionality and isn't advisable. diff -r f98f716b2ae8 -r 3a28047ec6dc src/hg-ssh --- a/src/hg-ssh Wed Dec 02 17:46:28 2009 +0000 +++ b/src/hg-ssh Wed Dec 02 17:48:40 2009 +0000 @@ -14,12 +14,8 @@ hg-ssh - limit access to hg repositories reached via ssh. Part of mercurial-server. -This script is called by hg-ssh-wrapper with no arguments - everything -should be in enviroment variables: - -HG_ACCESS_RULES_PATH identifies the paths to the rule files -REMOTE_USER the remote user (which is the key used by ssh) -SSH_ORIGINAL_COMMAND the command the user was trying to run +It is called by ssh due to an entry in the authorized_keys file, +with the name for the key passed on the command line. 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 @@ -35,7 +31,7 @@ import sys, os, os.path import base64 -from mercurialserver import ruleset, paths +from mercurialserver import config, ruleset def fail(message): sys.stderr.write("mercurial-server: %s\n" % message) @@ -71,7 +67,7 @@ checkParents(repo) return repo -paths.setExePath() +config.initExe() if len(sys.argv) == 3 and sys.argv[1] == "--base64": ruleset.rules.set(user = base64.b64decode(sys.argv[2])) @@ -81,14 +77,12 @@ fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" % sys.argv) -# Use a different hgrc for remote pulls - this way you can set -# up access.py for everything at once without affecting local operations +for k,v in config.getEnv(): + os.environ[k] = v -os.environ['HGRCPATH'] = paths.getHgrcPaths() +os.chdir(config.getReposPath()) -os.chdir(paths.getReposPath()) - -for f in paths.getAccessPaths(): +for f in config.getAccessPaths(): if os.path.isfile(f): ruleset.rules.readfile(f) diff -r f98f716b2ae8 -r 3a28047ec6dc src/init/conf/remote-hgrc --- a/src/init/conf/remote-hgrc Wed Dec 02 17:46:28 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -# hgrc to use for all remote users - -[hooks] -pretxnchangegroup.access = python:mercurialserver.access.hook -changegroup.aaaaa_servelog = python:mercurialserver.servelog.hook -outgoing.aaaaa_servelog = python:mercurialserver.servelog.hook diff -r f98f716b2ae8 -r 3a28047ec6dc src/init/conf/remote-hgrc.d/access.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/init/conf/remote-hgrc.d/access.rc Wed Dec 02 17:48:40 2009 +0000 @@ -0,0 +1,5 @@ +# Check that a commit meets access control rules before allowing it + +[hooks] +pretxnchangegroup.access = python:mercurialserver.access.hook + diff -r f98f716b2ae8 -r 3a28047ec6dc src/init/conf/remote-hgrc.d/logging.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/init/conf/remote-hgrc.d/logging.rc Wed Dec 02 17:48:40 2009 +0000 @@ -0,0 +1,5 @@ +# Log every push and pull to the servelog + +[hooks] +changegroup.aaaaa_servelog = python:mercurialserver.servelog.hook +outgoing.aaaaa_servelog = python:mercurialserver.servelog.hook diff -r f98f716b2ae8 -r 3a28047ec6dc src/init/dot-mercurial-server --- a/src/init/dot-mercurial-server Wed Dec 02 17:46:28 2009 +0000 +++ b/src/init/dot-mercurial-server Wed Dec 02 17:48:40 2009 +0000 @@ -3,7 +3,13 @@ [paths] repos = ~/repos +authorized_keys = ~/.ssh/authorized_keys keys = /etc/mercurial-server/keys:~/repos/hgadmin/keys access = /etc/mercurial-server/access.conf:~/repos/hgadmin/access.conf -hgrc = /etc/mercurial-server/remote-hgrc +[env] +# Use a different hgrc for remote pulls - this way you can set +# up access.py for everything at once without affecting local operations + +HGRCPATH = /etc/mercurial-server/remote-hgrc.d + diff -r f98f716b2ae8 -r 3a28047ec6dc src/mercurialserver/config.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mercurialserver/config.py Wed Dec 02 17:48:40 2009 +0000 @@ -0,0 +1,50 @@ +# Copyright 2008-2009 LShift Ltd + +import sys +import os +import os.path +import pwd +import ConfigParser + +globalconfig = None + +def _getConf(): + global globalconfig + if globalconfig is None: + globalconfig = ConfigParser.RawConfigParser() + globalconfig.read(os.path.expanduser("~/.mercurial-server")) + return globalconfig + +def _getPath(name): + return os.path.expanduser(_getConf().get("paths", name)) + +def _getPaths(name): + return [os.path.expanduser(p) + for p in _getConf().get("paths", name).split(":")] + +def getReposPath(): return _getPath("repos") +def getAuthorizedKeysPath(): return _getPath("authorized_keys") + +def configExists(): + try: + getAuthorizedKeysPath() + return True + except Exception, e: + print e + return False + +def getKeysPaths(): return _getPaths("keys") +def getAccessPaths(): return _getPaths("access") + +def getEnv(): return _getConf().items("env") + +# Work out where we are, don't use config. +def initExe(): + global _exePath + _exePath = os.path.dirname(os.path.abspath(sys.argv[0])) + # Fix $HOME in case of "sudo -u hg refresh-auth" + os.environ['HOME'] = pwd.getpwuid(os.geteuid()).pw_dir + +def getExePath(): + return _exePath + diff -r f98f716b2ae8 -r 3a28047ec6dc src/mercurialserver/paths.py --- a/src/mercurialserver/paths.py Wed Dec 02 17:46:28 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -# Copyright 2008-2009 LShift Ltd - -import sys -import os.path -import mercurial.config - -globalconfig = None - -def _getConf(): - global globalconfig - if globalconfig is None: - globalconfig = mercurial.config.config() - globalconfig.read(os.path.expanduser("~/.mercurial-server")) - return globalconfig - -def configExists(): - try: - _getConf() - return True - except: - return False - -def _getPath(name): - return os.path.expanduser(_getConf()["paths"][name]) - -def _getPaths(name): - return [os.path.expanduser(p) - for p in _getConf()["paths"][name].split(":")] - - -def getExePath(): return _getPath("exe") -def getReposPath(): return _getPath("repos") - -def getKeysPaths(): return _getPaths("keys") -def getAccessPaths(): return _getPaths("access") - -# This goes into an env var, so pass it on verbatim. -def getHgrcPaths(): return _getConf()["paths"]["hgrc"] - -# Work out where we are, don't use config. -def setExePath(): - global _exePath - _exePath = os.path.dirname(os.path.abspath(sys.argv[0])) - -def getExePath(): - return _exePath - diff -r f98f716b2ae8 -r 3a28047ec6dc src/mercurialserver/refreshauth.py --- a/src/mercurialserver/refreshauth.py Wed Dec 02 17:46:28 2009 +0000 +++ b/src/mercurialserver/refreshauth.py Wed Dec 02 17:48:40 2009 +0000 @@ -10,13 +10,13 @@ import os import os.path import subprocess -from mercurialserver import paths +from mercurialserver import config goodkey = re.compile("[/A-Za-z0-9._-]+$") def refreshAuth(): - akeyfile = os.path.expanduser("~/.ssh/authorized_keys") - wrappercommand = paths.getExePath() + "/hg-ssh" + akeyfile = config.getAuthorizedKeysPath() + wrappercommand = config.getExePath() + "/hg-ssh" prefix='no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=' if os.path.exists(akeyfile): @@ -29,7 +29,7 @@ f.close() akeys = open(akeyfile + "_new", "w") - for keyroot in paths.getKeysPaths(): + for keyroot in config.getKeysPaths(): kr = keyroot + "/" #print "Processing keyroot", keyroot for root, dirs, files in os.walk(keyroot): diff -r f98f716b2ae8 -r 3a28047ec6dc src/refresh-auth --- a/src/refresh-auth Wed Dec 02 17:46:28 2009 +0000 +++ b/src/refresh-auth Wed Dec 02 17:48:40 2009 +0000 @@ -8,17 +8,18 @@ import sys import os -from mercurialserver import refreshauth, paths +from mercurialserver import refreshauth, config if len(sys.argv) != 1: sys.stderr.write("refresh-auth: must be called with no arguments (%s)\n" % sys.argv) sys.exit(-1) +config.initExe() + # To protect the authorized_keys file for innocent users, you have to have # a ~/.mercurial-server file to run this. -if not paths.configExists(): +if not config.configExists(): print >>sys.stderr, "Must be run as the 'hg' user" sys.exit(-1) -paths.setExePath() refreshauth.refreshAuth()