README
changeset 83 86ec1268d306
parent 82 7369ff737684
child 100 db219a5a14f8
equal deleted inserted replaced
82:7369ff737684 83:86ec1268d306
   114 not necessarily the repository server) and you want to give them user-level
   114 not necessarily the repository server) and you want to give them user-level
   115 access to the repository server. Run these commands:
   115 access to the repository server. Run these commands:
   116 
   116 
   117     hg clone ssh://hg@repository-server/hgadmin
   117     hg clone ssh://hg@repository-server/hgadmin
   118     cd hgadmin
   118     cd hgadmin
   119     mkdir keys/user/thatuser
   119     mkdir keys/users/thatuser
   120     cp /tmp/theirkey keys/user/thatuser/theirhostname
   120     cp /tmp/theirkey keys/users/thatuser/theirhostname
   121     hg add
   121     hg add
   122     hg commit -m "Added key for thatuser"
   122     hg commit -m "Added key for thatuser"
   123     hg push
   123     hg push
   124 
   124 
   125 In other words, hgadmin is a version controlled version of
   125 In other words, hgadmin is a version controlled version of
   126 "/etc/mercurial-server/keys", and changes to it take effect immediately. Only
   126 "/etc/mercurial-server", and changes to it take effect immediately -
   127 "keys/root" users can act on "hgadmin" - those with keys in "keys/users" are
   127 "refresh-auth" is run after every push. 
   128 locked out. Multiple admins can use Mercurial's version control to cooperate
       
   129 on controlling access to the repository server in a natural way. You can also
       
   130 add "root" users by putting their key in the "keys/root" directory in just the
       
   131 same way - these users will now be able to control hgadmin and create new
       
   132 repositories just as you can.
       
   133 
   128 
   134 Once you're working with "hgadmin", it can be convenient to remove all the
   129 With the default access.conf file (see doc/configuring-access for more
   135 keys in "/etc/mercurial-server/keys" and all the entries in
   130 details) only users in "keys/root" can act on "hgadmin" - those with keys in
       
   131 "keys/users" cannot even read this repository. So multiple admins can use
       
   132 Mercurial's version control to cooperate on controlling access to the
       
   133 repository server in a natural way.
       
   134 
       
   135 You can also create an "access.conf" file in hgadmin, and this is appended to
       
   136 /etc/mercurial-server/access.conf whenever this is read - in other words,
       
   137 rules in the latter take precedence over those in the former. So once you're
       
   138 working with "hgadmin", it can be convenient to remove all the keys in
       
   139 "/etc/mercurial-server/keys" and all the entries in
   136 "/etc/mercurial-server/access.conf" and use hgadmin to control everything. If
   140 "/etc/mercurial-server/access.conf" and use hgadmin to control everything. If
   137 you find yourself locked out, you can get back in again by restoring some of
   141 you find yourself locked out, you can get back in again by restoring some of
   138 the entries you removed from these files - remember,
   142 the entries you removed from these files.
   139 "/etc/mercurial-server/access.conf" takes precedence over the "access.conf" in
       
   140 "hgadmin".
       
   141 
   143 
   142 ACCESS.CONF
   144 MORE INFORMATION
   143 
   145 
   144 Out of the box, there are just two kinds of users: the ones with keys in
   146 For more on how to use mercurial-server and configure access, see the files in
   145 "keys/root" and those in "keys/users". However, you can change this by editing
   147 the doc directory.
   146 "access.conf". There are two "access.conf" files, one in
       
   147 "/etc/mercurial-server" and one in "hgadmin"; the two are simply concatenated
       
   148 before being read.
       
   149 
       
   150 Each line of access.conf has the following syntax:
       
   151 
       
   152 <rule> <condition> <condition> ...
       
   153 
       
   154 Rule is one of
       
   155 
       
   156 init - allow any operation, including the creation of new repositories
       
   157 write - allow reads and writes to this file in this repository
       
   158 read - allow the repo to be read but reject matching writes
       
   159 deny - deny all requests
       
   160 
       
   161 A condition is a globpattern matched against a relative path, one of:
       
   162 
       
   163 user=<globpattern> - user's key
       
   164 repo=<globpattern> - repo (as the user supplies it)
       
   165 file=<globpattern> - file in the repo
       
   166 branch=<globpattern> - name of the branch
       
   167 
       
   168 The first rule in the file which has all its conditions satisfied is used to
       
   169 determine whether an action is allowed.
       
   170 
       
   171 Paths cannot contain any special characters except "/"; glob patterns cannot
       
   172 contain any special characters except "/" and "*". "*" matches zero or more
       
   173 characters not including "/" while "**" matches zero or more characters
       
   174 including "/".
       
   175 
       
   176 Blank lines and lines that start with "#" are ignored.
       
   177 
       
   178 FILE CONDITIONS
       
   179 
       
   180 mercurial-server supports file and branch conditions, which restrict an
       
   181 operation depending on what files it modifies and what branch the work is on.
       
   182 However, the way these conditions work is subtle and can be counterintuitive -
       
   183 if you want to keep things simple, stick to user and repo conditions, and then
       
   184 things are likely to work the way you would expect.
       
   185 
       
   186 The rules file is used to make four decisions:
       
   187 
       
   188 - Whether to allow a repository to be created
       
   189 - Whether to allow access to a repository
       
   190 - Whether to allow a changeset on a particular branch at all
       
   191 - Whether to allow a changeset to change a particular file
       
   192 
       
   193 When the first two of these decisions are being made, nothing is known about
       
   194 what files might be changed, and so all file conditions automatically succeed
       
   195 for the purpose of such decisions. This means that doing tricky things with
       
   196 file conditions can have counterintuitive consequences:
       
   197 
       
   198 - You cannot limit read access to a subset of a repository with a "read" rule
       
   199 and a file condition: any user who has access to a repository can read all of
       
   200 it and its full history. Such a rule can only have the effect of masking a
       
   201 later "write" rule, as in this example:
       
   202 
       
   203    read repo=specialrepo file=dontwritethis
       
   204    write repo=specialrepo
       
   205 
       
   206 allows all users to read specialrepo, and to write to all files *except* that
       
   207 any changeset which writes to "dontwritethis" will be rejected.
       
   208 
       
   209 - For similar reasons, don't give "init" rules file conditions.
       
   210 
       
   211 - Don't try to deny write access to a particular file on a particular branch -
       
   212 a developer can write to the file on another branch and then merge it in.
       
   213 Either deny all writes to the branch from that user, or allow them to write to
       
   214 all the files they can write to on any branch. In other words, something like
       
   215 this will have the intended effect:
       
   216 
       
   217   write user=docs/* branch=docs file=docs/*
       
   218 
       
   219 But something like this will not have the intended effect; it will effectively
       
   220 allow these users to write to any file on any branch, by writing it to "docs"
       
   221 first:
       
   222 
       
   223   write user=docs/* branch=docs
       
   224   write user=docs/* file=docs/*
       
   225   read user=docs/*
       
   226 
       
   227 HOW IT WORKS
       
   228 
       
   229 When a developer attempts to connect to a repository via ssh, the SSH daemon
       
   230 searches for a match for that user's key in ~hg/.ssh/authorized_keys. If the
       
   231 developer is authorised to connect to the repository they will have an entry
       
   232 in this file. The entry includes a "command" prefix which specifies that the
       
   233 restricted shell "/usr/local/lib/mercurial-server/hg-ssh" should be used; this
       
   234 shell is passed an argument identifying the developer. The shell parses the
       
   235 command the developer is trying to execute, and consults a rules file to see
       
   236 if that developer is allowed to perform that action on that repository.
       
   237 
       
   238 The file ~hg/.ssh/authorized_keys is generated by "refresh-auth", which
       
   239 recurses through two directories of files containing SSH keys and generates an
       
   240 entry in authorized_keys for each one, using the name of the key file as the
       
   241 identifier for the developer. These keys will live in the "keys" subdirectory
       
   242 "/etc/mercurial-server" and the "keys" subdirectory of a repository called
       
   243 "hgadmin". A hook in this repository re-runs "refresh-auth" on the most recent
       
   244 version after every push.
       
   245 
       
   246 Finally, hook in an extension is run for each changeset that is remotely
       
   247 committed, which uses the rules file to determine whether to allow the
       
   248 changeset.
       
   249 
       
   250 SECURITY OF MERCURIAL-SERVER
       
   251 
       
   252 mercurial-server relies entirely on sshd to grant access to remote users. As a
       
   253 result, it runs no daemons, installs no setuid programs, and no part of it
       
   254 runs as root except the install process: all programs run as the user hg. And
       
   255 any attack on mercurial-server can only be started if the Bad Guys already
       
   256 have a public key in ~hg/.ssh/authorized_keys, otherwise sshd will bar the
       
   257 way. No matter what command the user tries to run on the remote system via
       
   258 ssh, mercurial-server is run. 
       
   259 
       
   260 It parses the command line the user asked for, and interprets and runs the
       
   261 corresponding hg operation itself if access is allowed, so users can only read
       
   262 and add to history within repositories; they cannot run any other hg command.
       
   263 In addition, every push and pull is logged with a datestamp, changeset ID and
       
   264 the key that performed the operation.
       
   265 
       
   266 However, while the first paragraph holds no matter what bugs mercurial-server
       
   267 contains, the second depends on the relevant code being correct; though the
       
   268 entire codebase is currently only about twice as long as this README,
       
   269 mercurial-server is a fairly new program and may harbour bugs. Backups are
       
   270 essential!
       
   271 
   148 
   272 THANKS
   149 THANKS
   273 
   150 
   274 Thanks for reading this far. If you use mercurial-server, please tell me about
   151 Thanks for reading this far. If you use mercurial-server, please tell me about
   275 it.
   152 it.