bzr serve and access control?

Josef Wolf jw at raven.inka.de
Thu Feb 4 18:55:44 GMT 2010


On Thu, Feb 04, 2010 at 12:38:32PM +1100, Andrew Bennetts wrote:

> If I were to implement this, it would look like this:
> 
>   * set command="bzr acl-serve /path/to/acl-config" in your authorized_keys,
>   * have that config file define read/write permissions for various combinations
>     of paths and users,
>   * and write (and install system-wide) a plugin that implements 'bzr acl-serve'.
> 
> The plugin would:
> 
>   * register the 'acl-serve' command, which would:
>     * parse the config file determine the SSH user,
>     * using that info register an 'aclbzr' server in
>       bzrlib.transport.transport_server_registry, then
>     * run 'bzr serve --inet --protocol=aclbzr --directory=something'

So again, the directory is pretty much hardwired for a given user. Again,
flexibility is very limited here. For example, you can not specify multiple
directory hierarchies for a given user while excluding sub hierarchies.

For example, to serve my git repositories, I have configured a hierarchy
like this:

 # note: C==create, R==read, W==write, D==delete
 #
 /srv/repos/public/everybody  everybody can CRW here
 /srv/repos/public/<user>     user <user> can CRWD, everybody can R
 /srv/repos/private/<user>    user <user> can CRWD
 /srv/repos/some_repo         Some users can R, some can W, some can CD
 /srv/repos/other_repo        Some users can R, some can W, some can CD
 /srv/repos/one_more_repo     Some users can R, some can W, some can CD
 /srv/repos/repo              Some users can R, some can W, some can CD
 /srv/repos/repo/hierarchy    Some users can R, some can W, some can CD

Try to do that if you have only one --directory setting per user.

>   * the 'aclbzr' server would be a function that works much like
>     bzrlib.smart.serve.serve_bzr (the default implementation), but uses a
>     custom transport decorator to enforce ACLs before passing requests to the
>     underlying LocalTransport.
> 
> It's the custom transport part that is the key here.  You could pretty easily
> use PathFilteringTransport (from bzrlib.transport.pathfilter) to enforce “can
> see this path or not”.  You'd need to do something a little more complicated to
> enforce “can only read from this path, regardless of filesystem permissions” I
> think, but probably pretty easy by simply subclassing PathFilteringTransport and
> overriding the handful of write methods (append_file, delete, delete_tree,
> lock_read, mkdir, open_write_stream, put_file, rename, rmdir).  The
> ClueBzrServer mentioned elsewhere in this thread also uses a custom transport at
> its core.
> 
> I'd be happy to elaborate further if someone is interested in implementing this.
> I don't think it's actually very hard, but there's a fair bit of glue code
> involved, as my terse description above suggests.

Well, it sounds pretty complicated to me. And you have to touch bzr internals,
so really good knowledge about bazaar internals are needed to implement this
properly. And it is not backwards compatible.

Look, I have implemented the thing described above for git in less than 50
(trivial) lines of perl. Without knowing about git internals and without
touching git at all. Just a matter of getting directory and access method
from the command line and act according the config file. Not a big deal.
Took me less than two hours and I can be 100% sure I have not broken anything
in git. And since the code is trivial, it is easy to check for correctness.

Implementing your proposal would take me at least a month and would
have a big risk to break something. And it would still not give me the
flexibility that I already have with the damn 50 lines of trivial perl for
git.



More information about the bazaar mailing list