# HG changeset patch # User Paul Crowley # Date 1235065866 0 # Node ID f5055ce263c77d971888955a45be38fa08f8be37 # Parent f1ee930c4ba88e6eb50ebedb2c017d51e653760a New system. No breaking in, just putting files in /etc/mercurial-server diff -r f1ee930c4ba8 -r f5055ce263c7 install --- a/install Thu Feb 19 16:36:41 2009 +0000 +++ b/install Thu Feb 19 17:51:06 2009 +0000 @@ -4,22 +4,22 @@ install -o root -g root -d /usr/local/lib/mercurial-server install -o root -g root -t /usr/local/lib/mercurial-server \ + src/hg-ssh \ + src/do-refresh-auth +install -o root -g root -t /usr/local/lib/mercurial-server -m 644 \ src/access.py \ - src/hg-ssh \ - src/refresh-auth \ src/ruleset.py install -o root -g root -d /usr/local/lib/mercurial-server/init install -o root -g root -t /usr/local/lib/mercurial-server/init \ - src/init/hginit \ + src/init/hginit +install -o root -g root -t /usr/local/lib/mercurial-server/init -m 644 \ src/init/hgadmin-hgrc -install -o root -g root -d /usr/local/lib/mercurial-server/init/break-in -install -o root -g root -t /usr/local/lib/mercurial-server/init/break-in \ - src/init/break-in/create-breakin-repository \ - src/init/break-in/ssh-replacement \ - src/init/break-in/as-if-by-ssh \ - src/init/break-in/break-in install -o root -g root -d /etc/mercurial-server install -o root -g root -t /etc/mercurial-server \ src/init/conf/hg-ssh-wrapper \ - src/init/conf/remote-hgrc + src/init/conf/refresh-auth +install -o root -g root -t /etc/mercurial-server -m 644 \ + src/init/conf/remote-hgrc \ + src/init/conf/access.conf +install -o root -g root -d /etc/mercurial-server/keys/root diff -r f1ee930c4ba8 -r f5055ce263c7 setup --- a/setup Thu Feb 19 16:36:41 2009 +0000 +++ b/setup Thu Feb 19 17:51:06 2009 +0000 @@ -7,3 +7,4 @@ adduser --system --shell /bin/sh --group --disabled-password \ --gecos "Mercurial repositories" hg su -c /usr/local/lib/mercurial-server/init/hginit hg + diff -r f1ee930c4ba8 -r f5055ce263c7 src/access.py --- a/src/access.py Thu Feb 19 16:36:41 2009 +0000 +++ b/src/access.py Thu Feb 19 17:51:06 2009 +0000 @@ -21,7 +21,8 @@ def __init__(self, ui, repo): self.ui = ui self.repo = repo - self.rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE']) + + self.rules = ruleset.rules_from_env() self.rules.set(user = os.environ['REMOTE_USER']) self.rules.set(repo = os.environ['HG_REPO_PATH']) diff -r f1ee930c4ba8 -r f5055ce263c7 src/do-refresh-auth --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/do-refresh-auth Thu Feb 19 17:51:06 2009 +0000 @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# WARNING +# This script completely destroys your ~/.ssh/authorized_keys +# file every time it is run +# WARNING + +import sys +import os +import os.path +import ruleset +import subprocess + +if len(sys.argv) <= 3: + sys.stderr.write("refresh-auth: wrong number of arguments (%s)\n" % sys.argv) + sys.exit(-1) + +akeyfile = sys.argv[1] +wrappercommand = sys.argv[2] +prefix='no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=' + +if os.path.exists(akeyfile): + f = open(akeyfile) + try: + for l in f: + if not l.startswith(prefix): + raise Exception("Safety check failed, delete %s to continue" % akeyfile) + finally: + f.close() + +akeys = open(akeyfile + "_new", "w") +for keyroot in sys.argv[3:]: + kr = keyroot + "/" + #print "Processing keyroot", keyroot + for root, dirs, files in os.walk(keyroot): + for fn in files: + ffn = os.path.join(root, fn) + if not ffn.startswith(kr): + print "Weird, walk returned unexpected result" + continue + #print "Processing file", ffn + keyname = ffn[len(kr):] + if not ruleset.goodpath(keyname): + # ignore any path that contains dodgy characters + #print "Ignoring file", ffn + continue + p = subprocess.Popen(("ssh-keygen", "-i", "-f", ffn), + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + newkey = p.communicate()[0] + if p.wait() == 0: + klines = [l.strip() for l in newkey.split("\n")] + else: + # Conversion failed, read it directly. + kf = open(ffn) + try: + klines = [l.strip() for l in kf] + finally: + kf.close() + for l in klines: + if len(l): + akeys.write('%s"%s %s" %s\n' % (prefix, wrappercommand, keyname, l)) + +akeys.close() + +os.rename(akeyfile + "_new", akeyfile) + diff -r f1ee930c4ba8 -r f5055ce263c7 src/hg-ssh --- a/src/hg-ssh Thu Feb 19 16:36:41 2009 +0000 +++ b/src/hg-ssh Thu Feb 19 17:51:06 2009 +0000 @@ -17,7 +17,7 @@ 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 +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 @@ -68,7 +68,7 @@ fail("hg-ssh must have no arguments (%s)" % sys.argv) -rules = ruleset.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE']) +rules = ruleset.rules_from_env() rules.set(user = getpath(os.environ['REMOTE_USER'])) rules.set(branch = None, file = None) todispatch = get_cmd(rules, diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/break-in/as-if-by-ssh --- a/src/init/break-in/as-if-by-ssh Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#!/bin/sh -# Used only for break-ins - -set -e -SSH_ORIGINAL_COMMAND=$1 -echo "SSH_ORIGINAL_COMMAND=$SSH_ORIGINAL_COMMAND" >&2 -export SSH_ORIGINAL_COMMAND -cd -exec /etc/mercurial-server/hg-ssh-wrapper root - diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/break-in/break-in --- a/src/init/break-in/break-in Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -#!/bin/sh - -set -e - -user=$(whoami) - -/usr/local/lib/mercurial-server/init/break-in/create-breakin-repository -cd hgadmin -mkdir -p keys -ssh-add -L > keys/$user -echo "init user=$user" > hg-ssh-access.conf -hg add keys/$user hg-ssh-access.conf -hg commit -m "Give all access only to user $user" -hg push diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/break-in/create-breakin-repository --- a/src/init/break-in/create-breakin-repository Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#!/bin/sh - -set -e - -hg clone -e /usr/local/lib/mercurial-server/init/break-in/ssh-replacement ssh://localhost/hgadmin -cd hgadmin -cat >> .hg/hgrc << __END__ -[ui] -ssh = /usr/local/lib/mercurial-server/init/break-in/ssh-replacement -__END__ -echo "cd to hgadmin, make changes and commit" - diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/break-in/do-breakin --- a/src/init/break-in/do-breakin Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -#!/bin/sh - -set -e - -HOME=~hg -export HOME -cd - -rm -rf temporary-breakin-repo -mkdir temporary-breakin-repo -cd temporary-breakin-repo -hg clone ~/repos/hgadmin . -if [ $(echo *) != "" ] ; then - DIRNAME=retry - while [ $DIRNAME = retry ] ; do - DIRNAME=$(date -u +"%F_%T.%N") - mkdir $DIRNAME || DIRNAME=retry - done - hg mv * $DIRNAME - hg mv -f $DIRNAME old -fi -hg echo "init user=initkey" > hg-ssh-access.conf -mkdir keys -cat > keys/initkey -hg add hg-ssh-access.conf keys/initkey -hg commit -m "Reset access to a single key via break-in script" -SSH_ORIGINAL_COMMAND= /etc/mercurial-server/hg-ssh-wrapper root - diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/break-in/ssh-replacement --- a/src/init/break-in/ssh-replacement Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#!/bin/sh -# Used only for break-ins - -echo "arg: $2" >&2 - -exec sudo -H -u hg /usr/local/lib/mercurial-server/init/break-in/as-if-by-ssh "$2" - diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/conf/access.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/init/conf/access.conf Thu Feb 19 17:51:06 2009 +0000 @@ -0,0 +1,2 @@ +init user=root/** + diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/conf/hg-ssh-wrapper --- a/src/init/conf/hg-ssh-wrapper Thu Feb 19 16:36:41 2009 +0000 +++ b/src/init/conf/hg-ssh-wrapper Thu Feb 19 17:51:06 2009 +0000 @@ -24,7 +24,7 @@ export REMOTE_USER cd repos -HG_ACCESS_RULES_FILE=$(pwd)/hgadmin/hg-ssh-access.conf -export HG_ACCESS_RULES_FILE +HG_ACCESS_RULES_PATH=/etc/mercurial-server/access.conf:$(pwd)/hgadmin/access.conf +export HG_ACCESS_RULES_PATH exec /usr/local/lib/mercurial-server/hg-ssh diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/conf/refresh-auth --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/init/conf/refresh-auth Thu Feb 19 17:51:06 2009 +0000 @@ -0,0 +1,18 @@ +#!/bin/sh + +# This file should live in /etc/mercurial-server. +# If your repository is laid out differently you may need to modify +# this file. + +set -e + +if [ `whoami` != 'hg' ] ; then + echo "Must be run as hg user" + return -1 +else + /usr/local/lib/mercurial-server/do-refresh-auth \ + ~hg/.ssh/authorized_keys \ + /etc/mercurial-server/hg-ssh-wrapper \ + /etc/mercurial-server/keys \ + ~hg/repos/hgadmin/keys +fi diff -r f1ee930c4ba8 -r f5055ce263c7 src/init/hgadmin-hgrc --- a/src/init/hgadmin-hgrc Thu Feb 19 16:36:41 2009 +0000 +++ b/src/init/hgadmin-hgrc Thu Feb 19 17:51:06 2009 +0000 @@ -4,5 +4,5 @@ [hooks] changegroup.aaaaa_update = hg update -C default > /dev/null changegroup.aaaab_purge = hg purge --all > /dev/null -changegroup.refreshauth = /usr/local/lib/mercurial-server/refresh-auth ~/.ssh/authorized_keys /etc/mercurial-server/hg-ssh-wrapper +changegroup.refreshauth = /etc/mercurial-server/refresh-auth diff -r f1ee930c4ba8 -r f5055ce263c7 src/refresh-auth --- a/src/refresh-auth Thu Feb 19 16:36:41 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -# WARNING -# This script completely destroys your ~/.ssh/authorized_keys -# file every time it is run -# WARNING - -import sys -import os -import os.path -import ruleset -import subprocess - -if len(sys.argv) != 3: - sys.stderr.write("refresh-auth: wrong number of arguments (%s)\n" % sys.argv) - sys.exit(-1) - -akeyfile = sys.argv[1] -wrappercommand = sys.argv[2] -prefix='no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=' - -if os.path.exists(akeyfile): - f = open(akeyfile) - try: - for l in f: - if not l.startswith(prefix): - raise Exception("Safety check failed, delete %s to continue" % akeyfile) - finally: - f.close() - -akeys = open(akeyfile + "_new", "w") -for root, dirs, files in os.walk("keys"): - for fn in files: - ffn = os.path.join(root, fn) - if not ruleset.goodpath(ffn): - # ignore any path that contains dodgy characters - continue - keyname = ffn[5:] - if keyname == "root": - # No key can claim root privileges - continue - p = subprocess.Popen(("ssh-keygen", "-i", "-f", ffn), - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - newkey = p.communicate()[0] - if p.wait() == 0: - klines = [l.strip() for l in newkey.split("\n")] - else: - # Conversion failed, read it directly. - kf = open(ffn) - try: - klines = [l.strip() for l in kf] - finally: - kf.close() - for l in klines: - if len(l): - akeys.write('%s"%s %s" %s\n' % (prefix, wrappercommand, keyname, l)) - -akeys.close() - -os.rename(akeyfile + "_new", akeyfile) - diff -r f1ee930c4ba8 -r f5055ce263c7 src/ruleset.py --- a/src/ruleset.py Thu Feb 19 16:36:41 2009 +0000 +++ b/src/ruleset.py Thu Feb 19 17:51:06 2009 +0000 @@ -7,6 +7,8 @@ import sys import re +import os +import os.path allowedchars = "A-Za-z0-9_-" @@ -74,9 +76,7 @@ a = self.matchrule(**kw) return a in self.levels and self.levels.index(a) <= self.levels.index(level) - @classmethod - def readfile(cls, fn): - res = cls() + def readfile(self, fn): try: f = open(fn) try: @@ -85,11 +85,16 @@ if len(l) == 0 or l.startswith("#"): continue l = l.split() - res.add(l[0], rule([c.split("=", 1) for c in l[1:]])) + 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 - return cls() - return res +def rules_from_env(): + res = Ruleset() + for f in os.environ['HG_ACCESS_RULES_PATH'].split(os.pathsep): + if os.path.isfile(f): + res.readfile(f) + return res +