When the http-backend is set up to allow anonymous read but
authenticated write, the http-backend manual suggests
catching only the "/git-receive-pack" POST of the packfile,
not the initial "info/refs?service=git-receive-pack" GET in
which we advertise refs.

This does work and is secure, as we do not allow any write
during the info/refs request, and the information in the ref
advertisement is the same that you would get from a fetch.

However, the configuration required by the server is
slightly more complex. The default `http.receivepack`
setting is to allow pushes if the webserver tells us that
the user authenticated, and otherwise to return a 403
("Forbidden"). That works fine if authentication is turned
on completely; the initial request requires authentication,
and http-backend realizes it is OK to do a push.

But for this "half-auth" state, no authentication has
occurred during the initial ref advertisement. The
http-backend CGI therefore does not think that pushing
should be enabled, and responds with a 403. The client
cannot continue, even though the server would have allowed
it to run if it had provided credentials.

It would be much better if the server responded with a 401,
asking for credentials during the initial contact. But
git-http-backend does not know about the server's auth
configuration (so a 401 would be confusing in the case of a
true anonymous server). Unfortunately, configuring Apache to
recognize the query string and apply the auth appropriately
to receive-pack (but not upload-pack) initial requests is

The site admin can work around this by just turning on
http.receivepack explicitly in its repositories. Let's
document this workaround.

Signed-off-by: Jeff King <p...@peff.net>
My understanding is that you can do query-string matching through a
clever use of mod-rewrite. I am not nearly clever nor interested in
Apache enough to figure it out, but if somebody does, it would be nice
to put the recipe here.

 Documentation/git-http-backend.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/git-http-backend.txt 
index 7b1e85c..f43980f 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -91,6 +91,15 @@ require authorization with a LocationMatch directive:
+In this mode, the server will not request authentication until the
+client actually starts the object negotiation phase of the push, rather
+than during the initial contact.  For this reason, you must also enable
+the `http.receivepack` config option in any repositories that should
+accept a push. The default behavior, if `http.receivepack` is not set,
+is to reject any pushes by unauthenticated users; the initial request
+will therefore report `403 Forbidden` to the client, without even giving
+an opportunity for authentication.
 To require authentication for both reads and writes, use a Location
 directive around the repository, or one of its parent directories:

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to