--- a/README Sat Mar 07 08:58:30 2009 +0000
+++ b/README Sat Mar 07 09:31:06 2009 +0000
@@ -116,158 +116,35 @@
hg clone ssh://hg@repository-server/hgadmin
cd hgadmin
- mkdir keys/user/thatuser
- cp /tmp/theirkey keys/user/thatuser/theirhostname
+ 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/keys", and changes to it take effect immediately. Only
-"keys/root" users can act on "hgadmin" - those with keys in "keys/users" are
-locked out. Multiple admins can use Mercurial's version control to cooperate
-on controlling access to the repository server in a natural way. You can also
-add "root" users by putting their key in the "keys/root" directory in just the
-same way - these users will now be able to control hgadmin and create new
-repositories just as you can.
+"/etc/mercurial-server", and changes to it take effect immediately -
+"refresh-auth" is run after every push.
-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
+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 - remember,
-"/etc/mercurial-server/access.conf" takes precedence over the "access.conf" in
-"hgadmin".
-
-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> <condition> <condition> ...
-
-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, one of:
-
-user=<globpattern> - user's key
-repo=<globpattern> - repo (as the user supplies it)
-file=<globpattern> - file in the repo
-branch=<globpattern> - name of the branch
-
-The first rule in the file which has all its conditions satisfied is used to
-determine whether an action is allowed.
-
-Paths cannot contain any special characters except "/"; glob patterns cannot
-contain any special characters except "/" and "*". "*" matches zero or more
-characters not including "/" while "**" matches zero or more characters
-including "/".
-
-Blank lines and lines that start with "#" are ignored.
-
-FILE CONDITIONS
-
-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.
-
-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:
+the entries you removed from these files.
- 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/*
-
-HOW IT WORKS
+MORE INFORMATION
-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/lib/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.
-
-Finally, hook in an extension is run for each changeset that is remotely
-committed, which uses the rules file to determine whether to allow the
-changeset.
-
-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 currently only about twice as long as this README,
-mercurial-server is a fairly new program and may harbour bugs. Backups are
-essential!
+For more on how to use mercurial-server and configure access, see the files in
+the doc directory.
THANKS
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/configuring-access Sat Mar 07 09:31:06 2009 +0000
@@ -0,0 +1,47 @@
+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> <condition> <condition> ...
+
+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=<globpattern> - user's key
+ repo=<globpattern> - 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.
+
+Paths cannot contain any special characters except "/"; glob patterns cannot
+contain any special characters except "/" and "*". "*" 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.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/file-conditions Sat Mar 07 09:31:06 2009 +0000
@@ -0,0 +1,61 @@
+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=<globpattern> - file in the repo
+ branch=<globpattern> - 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/*
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/how-it-works Sat Mar 07 09:31:06 2009 +0000
@@ -0,0 +1,22 @@
+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/lib/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.
+
+Finally, hook in an extension is run for each changeset that is remotely
+committed, which uses the rules file to determine whether to allow the
+changeset.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/security Sat Mar 07 09:31:06 2009 +0000
@@ -0,0 +1,21 @@
+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 currently only about twice as long as this README,
+mercurial-server is a fairly new program and may harbour bugs. Backups are
+essential!