Provide an entrypoint for a smart server authentication plugin

Bug #607717 reported by Glen Mailer
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Bazaar
Confirmed
Low
Unassigned

Bug Description

I've been looking into ways to do simple authentication for the smart server, I've been modelling my approach on gitosis (http://eagain.net/gitweb/?p=gitosis.git), which does have a few-years-old bazaar equivalent - bazitis (https://launchpad.net/bazitis). The general idea with these is to use a single unix user on the server, and a different command string for each public key - which passes a username in via argv.

The approach taken by bazitis to restrict access to individual directories (and thus branches) on the remote server is to replace the file:/// transport, and then authenticate against its config file. This seems unnecessarily complex. The reason it's done this way, is because when accessing over bzr+ssh, the SSH_ORIGINAL_COMMAND is always `bzr serve` with --directory=/, any information about the paths or actions is sent over the medium, not on initialisation.

What i'm looking for, is a neat way to drop a hook/authentication function into the smart server transport, which can then do whatever is needed.

I've done a rather hacky approach with a small plugin, that i'll put up somewhere once i've tidied it up a bit; the approach taken is thus:

1) ssh command wrapper sets environment variable BZR_AUTH_USER, then runs serve (it also restricts the root directory to a repositories directory).
2) a plugin monkeypatches the `bzrlib.smart.request.SmartServerRequest.translate_client_path` function, to run the path past a whitelist.
3) the whitelist checks the path/username combo and raises a PermissionDenied error if needed.

This actually works relatively neatly - but the monkeypatch isn't particularly pretty - especially as translate_client_path is called multiple times per operation.

Hope this explanation is clear enough.

Andrew Bennetts (spiv)
tags: added: hpss
Revision history for this message
Andrew Bennetts (spiv) wrote :

Technically we already provide an entry point for this, but it would be good to make this much easier to do and deploy, so I'm happy to accept this as a valid bug.

Your approach isn't far off how I'd recommend doing this with bzr today. I'd override 'serve' builtin command (or provide an alternative 'authed-serve' command, perhaps, based on the builtin cmd_serve) though to construct a server with a different root transport (rather than a LocalTransport of /). Depending on your needs this could be a simple ChrootTransport rooted at a user-specific directory, or perhaps something a bit more complicated. Basically, provide the virtual filesystem that you want to expose to the user. This is essentially how Launchpad's codehosting service works.

The building blocks for this are all in bzrlib (plugins can provide commands, the smart server can be started with a specific transport, there are helpers for making custom transports such as the bzrlib.transport.memory and bzrlib.transport.pathfilter modules, and there's solid test coverage and infrastructure for all of the above), but it's not trivial to put the pieces together. It would be lovely to provide a functional smart server access-control plugin as part of bzr, or at least in the contrib directory. The goal would be to have it be usable for simple/common cases, and be an instructive basis for building a custom plugin for people with more complex requirments.

This bug might be a duplicate of an existing bug, but I can't find it at the moment. Some loosely related bugs are bug 126991, bug 510545, bug 407247, and bug 576778.

Changed in bzr:
importance: Undecided → Low
status: New → Confirmed
Jelmer Vernooij (jelmer)
tags: added: check-for-breezy
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.