# HG changeset patch # User Paul Crowley # Date 1255607259 -3600 # Node ID 8d73bcd752430aa9b6f3a232ca0a4a170bff6dee # Parent 1c0bc7d336480f171404b9f732d56dd771605c74 remove precursors to Docbook manual diff -r 1c0bc7d33648 -r 8d73bcd75243 README --- a/README Thu Oct 15 12:28:08 2009 +0100 +++ b/README Thu Oct 15 12:47:39 2009 +0100 @@ -1,8 +1,8 @@ mercurial-server -mercurial-server makes a group of repositories available to the developers -you choose, identified by ssh keys, with easy key and access management -based on hg. +mercurial-server gives your developers remote read/write access to +centralized Mercurial repositories using SSH public key authentication; it +provides convenient and fine-grained key management and access control. http://www.lshift.net/mercurial-server.html @@ -22,134 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -SUMMARY - -mercurial-server makes a group of repositories available to the developers -you choose, identified by ssh keys, with easy key and access management -based on hg. - -All of the repositories controlled by mercurial-server are owned by a -single user (the "hg" user in what follows), but many remote users can act -on them, and different users can have different permissions. We don't use -file permissions to achieve that - instead, developers log in as the "hg" -user when they connect to the repository host using ssh, using ssh URLs of -the form "ssh://hg@repository-host/repository-name". A restricted shell -prevents them from using this access for unauthorized purposes. Developers -are authenticated only using SSH keys; no other form of authentication is -supported. - -To give a user access to the repository, place their key in an -appropriately-named subdirectory of "/etc/mercurial-server/keys" and run -"/usr/local/share/mercurial-server/refresh-auth". You can then control what -access they have to what repositories by editing the control file -"/etc/mercurial-server/access.conf", which can match the names of these keys -against a glob pattern. - -For convenient remote control of access, you can instead (if you have the -privileges) make changes to a special repository called "hgadmin", which -contains its own "access.conf" file and "keys" directory. Changes pushed to -this repository take effect immediately. The two "access.conf" files are -concatenated, and the keys directories merged. - -QUICK START - -You and all developers using this system will need an SSH public key, and -will almost certainly want to be running ssh-agent (or its equivalent, eg -Pageant under Windows). If you're not familiar with ssh-agent, you should -learn about that before using this. - -In what follows, certain operations (eg installing mercurial-server itself) -have to be done on the repository server (which we call "repository-host"), -but any operation that involves checking in or out of Mercurial can be done -wherever is most convenient to you; the most usual arrangment would be that -you'd do these things at the machine you sit at, and on which you run -ssh-agent, which is what authenticates you when you talk to the repository -server. - -Ensure there is no user called "hg" on the repository host, and run -"./install". This installs the mercurial-server files and control files, and -creates and sets up the "hg" user. - -Place your SSH public key in the directory "/etc/mercurial-server/keys/root". -I suggest creating yourself a directory and naming the key after your hostname -(ie the file is called something like -"/etc/mercurial-server/keys/root/yourname/yourhostname") so that you can -easily manage users who have a different key on each host they use. Then run -"/usr/local/share/mercurial-server/refresh-auth". - -The repository is now ready to use, and you are now the sole user able to -change and create repositories on this repository host. - -CREATING REPOSITORIES - -To create a new repository, you clone a local repository onto the remote -server. So if you want a new empty repository called "myproject", you can do -(as yourself): - - hg init myproject - hg clone myproject ssh://hg@repository-host/myproject - -ADDING OTHER USERS - -Because your key is in the "keys/root" subdirectory, you have the equivalent -of "root privileges" over mercurial-server (not the whole computer, just -mercurial-server). You can add other root users by putting their keys next to -yours, or you can make less privileged users by putting their keys in the -"keys/users" subdirectory - these users will be able to read and write to any -repository (except one - see below) but will not be able to create new -repositories. As always, when you change "/etc/mercurial-server/keys" you need -to re-run "/usr/local/share/mercurial-server/refresh-auth". - -LOGGING - -Every push and pull is logged with the key used: see the file .hg/serve-log in -each repository. - -USING HGADMIN - -It can be inconvenient to log on to the repository server, become root, copy -keys around, and run "refresh-auth" every time you want to change user -privileges. This is where mercurial-server shines :-) Suppose you have another -user's SSH public key in the file "/tmp/theirkey" (on the machine you sit at, -not necessarily the repository server) and you want to give them user-level -access to the repository server. Run these commands: - - hg clone ssh://hg@repository-server/hgadmin - cd hgadmin - mkdir keys/users/thatuser - cp /tmp/theirkey keys/users/thatuser/theirhostname - hg add - hg commit -m "Added key for thatuser" - hg push - -In other words, hgadmin is a version controlled version of -"/etc/mercurial-server", and changes to it take effect immediately - -"refresh-auth" is run after every push. - -With the default access.conf file (see doc/configuring-access for more -details) only users in "keys/root" can act on "hgadmin" - those with keys in -"keys/users" cannot even read this repository. So multiple admins can use -Mercurial's version control to cooperate on controlling access to the -repository server in a natural way. - -You can also create an "access.conf" file in hgadmin, and this is appended to -/etc/mercurial-server/access.conf whenever this is read - in other words, -rules in the latter take precedence over those in the former. So once you're -working with "hgadmin", it can be convenient to remove all the keys in -"/etc/mercurial-server/keys" and all the entries in -"/etc/mercurial-server/access.conf" and use hgadmin to control everything. If -you find yourself locked out, you can get back in again by restoring some of -the entries you removed from these files. - -MORE INFORMATION - -For more on how to use mercurial-server and configure access, see the files in -the doc directory. - -THANKS - -Thanks for reading this far. If you use mercurial-server, please tell me about -it. +For details on how to install and use mercurial-server, see doc/manual.docbook. Paul Crowley, paul@lshift.net, 2009 diff -r 1c0bc7d33648 -r 8d73bcd75243 doc/configuring-access --- a/doc/configuring-access Thu Oct 15 12:28:08 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -ACCESS.CONF - -Out of the box, there are just two kinds of users: the ones with keys in -"keys/root" and those in "keys/users". However, you can change this by -editing "access.conf". There are two "access.conf" files, one in -"/etc/mercurial-server" and one in "hgadmin"; the two are simply -concatenated before being read. - -Each line of access.conf has the following syntax: - - ... - -Rule is one of - -init - allow any operation, including the creation of new repositories -write - allow reads and writes to this file in this repository -read - allow the repo to be read but reject matching writes -deny - deny all requests - -A condition is a globpattern matched against a relative path. The two most -important conditions are - - user= - user's key - repo= - repo (as the user supplies it) - -The first rule in the file which has all its conditions satisfied is used -to determine whether an action is allowed. If no rule is matched the -request is denied. - -"*" only matches one directory level, where "**" matches as many as you -want. More precisely, "*" matches zero or more characters not including "/" -while "**" matches zero or more characters including "/". - -Blank lines and lines that start with "#" are ignored. - -access.conf ships with the following contents: - - init user=root/** - deny repo=hgadmin - write user=users/** - -This means: keys in "root" can do anything; keys in "users" cannot create -repositories, cannot even read the hgadmin repository, but can read and -write any other repository; no other key has any access. - -More advanced access configuration is covered in file-conditions. - diff -r 1c0bc7d33648 -r 8d73bcd75243 doc/file-conditions --- a/doc/file-conditions Thu Oct 15 12:28:08 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -FILE CONDITIONS - -Read configuring-access before you read this. - -mercurial-server supports file and branch conditions, which restrict an -operation depending on what files it modifies and what branch the work is -on. However, the way these conditions work is subtle and can be -counterintuitive - if you want to keep things simple, stick to user and -repo conditions, and then things are likely to work the way you would -expect. - -File and branch conditions are added to the conditions against which a rule -matches, just like user and repo conditions; they have this form: - - file= - file in the repo - branch= - name of the branch - -However, in order to understand what effect adding these conditions will -have, it helps to understand how and when these rules are applied. - -The rules file is used to make four decisions: - -- Whether to allow a repository to be created -- Whether to allow access to a repository -- Whether to allow a changeset on a particular branch at all -- Whether to allow a changeset to change a particular file - -When the first two of these decisions are being made, nothing is known -about what files might be changed, and so all file conditions automatically -succeed for the purpose of such decisions. This means that doing tricky -things with file conditions can have counterintuitive consequences: - -- You cannot limit read access to a subset of a repository with a "read" -rule and a file condition: any user who has access to a repository can read -all of it and its full history. Such a rule can only have the effect of -masking a later "write" rule, as in this example: - - read repo=specialrepo file=dontwritethis - write repo=specialrepo - -allows all users to read specialrepo, and to write to all files *except* -that any changeset which writes to "dontwritethis" will be rejected. - -- For similar reasons, don't give "init" rules file conditions. - -- Don't try to deny write access to a particular file on a particular -branch - a developer can write to the file on another branch and then merge -it in. Either deny all writes to the branch from that user, or allow them -to write to all the files they can write to on any branch. In other words, -something like this will have the intended effect: - - write user=docs/* branch=docs file=docs/* - -But something like this will not have the intended effect; it will -effectively allow these users to write to any file on any branch, by -writing it to "docs" first: - - write user=docs/* branch=docs - write user=docs/* file=docs/* - read user=docs/* - - diff -r 1c0bc7d33648 -r 8d73bcd75243 doc/how-it-works --- a/doc/how-it-works Thu Oct 15 12:28:08 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -HOW IT WORKS - -When a developer attempts to connect to a repository via ssh, the SSH -daemon searches for a match for that user's key in -~hg/.ssh/authorized_keys. If the developer is authorised to connect to the -repository they will have an entry in this file. The entry includes a -"command" prefix which specifies that the restricted shell -"/usr/local/share/mercurial-server/hg-ssh" should be used; this shell is -passed an argument identifying the developer. The shell parses the command -the developer is trying to execute, and consults a rules file to see if -that developer is allowed to perform that action on that repository. - -The file ~hg/.ssh/authorized_keys is generated by "refresh-auth", which -recurses through two directories of files containing SSH keys and generates -an entry in authorized_keys for each one, using the name of the key file as -the identifier for the developer. These keys will live in the "keys" -subdirectory "/etc/mercurial-server" and the "keys" subdirectory of a -repository called "hgadmin". A hook in this repository re-runs -"refresh-auth" on the most recent version after every push. - -When users try to commit new changesets, a hook is run which consults the -rules file to decide whether to allow the changeset into the repository. -This can depend not only on the user and the repository, but also the -branch and files in the changeset. diff -r 1c0bc7d33648 -r 8d73bcd75243 doc/security --- a/doc/security Thu Oct 15 12:28:08 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -SECURITY OF MERCURIAL-SERVER - -mercurial-server relies entirely on sshd to grant access to remote users. -As a result, it runs no daemons, installs no setuid programs, and no part -of it runs as root except the install process: all programs run as the user -hg. And any attack on mercurial-server can only be started if the Bad Guys -already have a public key in ~hg/.ssh/authorized_keys, otherwise sshd will -bar the way. - -No matter what command the user tries to run on the remote system via ssh, -mercurial-server is run. It parses the command line the user asked for, and -interprets and runs the corresponding hg operation itself if access is -allowed, so users can only read and add to history within repositories; -they cannot run any other hg command. In addition, every push and pull is -logged with a datestamp, changeset ID and the key that performed the -operation. - -However, while the first paragraph holds no matter what bugs -mercurial-server contains, the second depends on the relevant code being -correct; though the entire codebase is short, mercurial-server is a fairly -new program and may harbour bugs. Backups are essential!