hg-admin-toolsA set of tools for managing authorization and access control forssh-based Mercurial repositoriesPaul Crowley, paul@lshift.net, 2008This software may be used and distributed according to the termsof the GNU General Public License, incorporated herein by reference.WHAT IT GIVES YOUYou maintain a local Mercurial repository called "hgadmin" whichcontrols what access is allowed to whom. When you push a new versionof this repository to the repository host, changes take effectimmediately, so familiar "hg" commands are all that are needed tomaintain it. A "keys" directory contains the SSH keys of all thedevelopers who have access, while "hg-ssh-access.conf" gives a set ofrules defining who can do what to what.HOW IT WORKSThe repository is owned by a single user (the "hg" user in whatfollows), but many remote users can act on it. We don't use filepermissions to achieve that - instead, developers log in as the "hg"user when they connect to the repository host using ssh, using sshURLs of the form "ssh://hg@repository-host/repository-name". Arestricted shell prevents them from using this access for unauthorizedpurposes.Developers are authenticated only using SSH keys; no other form ofauthentication is supported. When a developer attempts to connect toa repository via ssh, the SSH daemon searches for a match for thatuser's key in ~hg/.ssh/authorized_keys. If the developer isauthorised to connect to the repository they will have an entry inthis file. The entry includes a "command" prefix which specifies thatthe restricted shell should be used; this shell is passed an argumentidentifying the developer. The shell parses the command the developeris trying to execute, and consults a rules file to see if thatdeveloper is allowed to perform that action on that repository. Thebulk of the work of the restricted shell is done by the Python program"hg-ssh", but the shell script "hg-ssh-wrapper" sets up someconfiguration so that you can change it to suit your local installation.The file ~hg/.ssh/authorized_keys is generated by "refresh-auth",which recurses through a directory of files containing SSH keys andgenerates an entry in authorized_keys for each one, using the name ofthe key file as the identifier for the developer. These keys willlive in the "keys" subdirectory of a repository, "hgadmin". A hook inthis repository re-runs "refresh-auth" on the most recent versionafter every push.GETTING STARTEDThis is only one setup - it can be tweaked in many ways, and is asspecific as it is only in the interests of brevity.You, and all users of your Hg repository, will need SSH public keyauthentication set up, preferably working with ssh-agent so you don'thave to type in your passphrase all the time. I assume you've donethat in what follows, so if you've done something different you'llneed to change it appropriately.Create a user called "hg" on the machine where the repository willlive. I used the command sudo adduser --system --shell /bin/sh --group --disabled-password \ --gecos "Mercural repository" hgIssue these commands to become the hg user and set up the repository.Use your own name in place of "myname". ssh-add -L >> /tmp/my-ssh-public-key sudo -u hg -s cd ~hg mkdir -p admin repos/hgadmin/keys/admin cd admin hg clone http://hg.opensource.lshift.net/hg-admin-tools cp hg-admin-tools/hg-ssh-wrapper ~ cd ../repos/hgadmin hg init . echo "init admin/* *" > hg-ssh-access.conf cp /tmp/my-ssh-public-key keys/admin/myname hg add hg commit cp ~/admin/hg-admin-tools/hgadmin-hgrc .hg/hgrc ../../admin/hg-admin-tools/refresh-auth exitYou should now have SSH access to this repository and full control.To administer these controls (and test your access), check out hgadmin: mkdir ~/hg cd ~/hg hg clone ssh://hg@repository-host-name/hgadmin cd hgadminYou can now add other users by putting their keys in an appropriatesubdirectory of the "keys" directory, and control their access byediting hg-ssh-access.conf. Changes will take effect as soon as youpush them to the remote repository.HG-SSH-ACCESS.CONFEach line of hg-ssh-access.conf has the following syntax:<rule> <keypattern> <repositorypattern>The "rule" is either "init", "allow", or "deny". "keypattern" is aglob pattern matched against the name of the key used - for example,in our initial setup "admin/myname" matches "admin/*"."repositorypattern" is a pattern matched againt the repository name -so "hgadmin" matches "*". Only boring characters are allowed inpatterns and key and repository names - see the source for details.Blank lines and lines that start with "#" are ignored. The first ruleto match both the key and the repository applies: "deny" will deny allmatching requests, "allow" allows read/write access to existingrepositories, and "init" allows that and creation of new repositories.