Re: git-http-backend: anonymous read, authenticated write

2013-04-12 Thread Magnus Therning
On Thu, Apr 11, 2013 at 9:34 PM, Jeff King p...@peff.net wrote:
 On Thu, Apr 11, 2013 at 08:52:56AM +0200, Magnus Therning wrote:

  The documentation should probably make the use of http.receivepack more
  clear in this situation.

 I think that'd be good.  The fact that it wasn't until several mails
 into the thread that anyone thought of the http.receivepack setting
 also suggests that its use is a bit un-intuitive (even though it
 probably makes perfect sense and is a good solution).

 Yeah, I did not even think of http.receivepack because I have never had
 to set it before (it was turned on in the original tests that I built
 top of). I have the impression that the anonymous-read/authenticated-write
 setup you are using has not been all that commonly used. The example in
 the manpage dates back to 2009, but it was only in 2012 that we got a
 bug report that the client-side authentication handler has problems with
 it.

Really?  I certainly think it deserves a bit more attention than that.
 It may be that gitosis and other SSH-based solutions have been around
longer than git-http-backend, but from what I've understood from
reading, it fits very nicely in between git-daemon and the rather
heavy SSH-based stuff.

  But your fix under lighttpd is much better, as it asks for the
  credentials up front (which means the client does not go to any work
  creating a packfile just to find out that it does not have access).

 Yes, I think it also helps with my particular scenario where new repos
 will be added from time to time.  This way there is no second step,
 after `git init`, that must be remembered.

 Yeah, avoiding setting http.receivepack at all is helpful. Though note
 that you can also set it in /etc/gitconfig for the whole system at once.

Good point.

/M

-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus
--
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


Re: git-http-backend: anonymous read, authenticated write

2013-04-11 Thread Magnus Therning
On Thu, Apr 11, 2013 at 3:56 AM, Jeff King p...@peff.net wrote:
 On Thu, Apr 11, 2013 at 01:19:19AM +0200, Magnus Therning wrote:

 Nope.  I'm pretty sure this had *nothing* to do with my config.  This
 is the original config, which doesn't work:

 $HTTP[url] =~ ^/git {
 cgi.assign = (  =  )
 setenv.add-environment = (
 GIT_PROJECT_ROOT = /srv/git,
 GIT_HTTP_EXPORT_ALL = 
 )
 $HTTP[url] =~ ^/git/.*/git-receive-pack$ {
 include trac-git-auth.conf
 }
 }

 Ah, I think I see what it is.

 Did you turn on http.receivepack in the git config to enable pushing?

Nope, of course I didn't :)  Instead I did what the man-page tells me
will allow full export of a git repo *without* having to fiddle around
with the repo's config:

1. set GIT_HTTP_EXPORT_ALL in the environment
2. turn on authentication for *one* location that requires it for
pushing: ^/git/.*/git-receive-pack$

[...]
 If there is no authentication happening for the initial service-request,
 then the default http.receivepack kicks in, which is to turn pushing
 off (because there is no authenticated user).

Yes, but that only becomes clear when looking at the traffic.  In
fact, the whole design of services is not clearly mentioned in the
man-page.  I was *very* surprised to see the query strings when I
started looking at the access logs.

 The documentation should probably make the use of http.receivepack more
 clear in this situation.

I think that'd be good.  The fact that it wasn't until several mails
into the thread that anyone thought of the http.receivepack setting
also suggests that its use is a bit un-intuitive (even though it
probably makes perfect sense and is a good solution).

 So _if_ you fixed it by setting http.receivepack (which I think is the
 simplest thing under Apache, since matching the query string there is
 hard), then you would need a version of git with that fix on the
 client side to actually have git prompt for the password correctly.

Ah, so *that* is the fix that has been mentioned (I haven't bothered
reading it myself), or are there in fact two fixes that have been
referred to in the thread?

 But your fix under lighttpd is much better, as it asks for the
 credentials up front (which means the client does not go to any work
 creating a packfile just to find out that it does not have access).

Yes, I think it also helps with my particular scenario where new repos
will be added from time to time.  This way there is no second step,
after `git init`, that must be remembered.

Thank you very much for taking the time to help me out with this!
I'll also take a look at the patches you sent, as a dumb simpler user
I might have something to add, who knows?

/M

--
Magnus Therning  OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus
--
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


Re: [PATCH 1/2] doc/http-backend: clarify half-auth repo configuration

2013-04-11 Thread Magnus Therning
On Thu, Apr 11, 2013 at 5:32 AM, Jeff King p...@peff.net wrote:
 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
 non-trivial.

 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 
 b/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:
  /LocationMatch
  
  +
 +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:
  +
 --
 1.8.2.rc0.33.gd915649


As the dumb user who started the thread that lead to this proposed
change, I do think this makes the documentation much clearer and had I
read this I most probably would have managed to set up the webserver
on my own.

/M

-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus
--
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


Re: git-http-backend: anonymous read, authenticated write

2013-04-10 Thread Magnus Therning
On Tue, Apr 09, 2013 at 01:12:47PM -0400, Jeff King wrote:
 On Tue, Apr 09, 2013 at 07:45:53AM +0200, Magnus Therning wrote:
 
 I've been trying to set up git-http-backend+lighttpd.  I've managed
 to set up anonymous read-only access, and I then successfully
 configured authentication for both read and write.  Then I get
 stuck.  The man-page for git-http-backend says that the following
 snippet can be used for Apache 2.x:
 
 LocationMatch ^/git/.*/git-receive-pack$
 AuthType Basic
 AuthName Git Access
 Require group committers
 ...
 /LocationMatch
 
 However, when I put in this match on location in my lighty config
 and try to push I'm not asked for a password, instead I'm greeted
 with
 
 % git push 
 error: The requested URL returned error: 403 Forbidden while accessing 
 http://magnus@tracsrv.local/git/foo.git/info/refs?service=git-receive-pack
 
 Something in your config is blocking access to info/refs there. It
 should not be the block shown above, which handles only the actual POST
 of the data. The sequence of http requests made is:
 
   1. GET $repo/info/refs?service=git-receive-pack
 
  This makes initial contact and gets the ref information which push
  uses to decide what it is going to push. So it is read-only, and in
  an anonymous-read setup, does not need to be protected.
 
   2. POST $repo/git-receive-pack
 
  This actually pushes up the objects and updates the refs, and
  must be protected.
 
 The setup listed above does work with apache; it is tested as part of
 our test suite (you can see the actual config in t/lib-httpd/apache.conf).
 So what in lighttpd is giving us the 403? Can you share your whole
 config?

I was putting together a *long* response, with my different
configurations when it suddenly hit me how to make it work.

So, this is the accesslog for a successful `git push`:

192.168.1.84 tracsrv.local - [10/Apr/2013:22:24:59 +0200] GET 
/git/foo.git/info/refs?service=git-receive-pack HTTP/1.1 401 351 - 
git/1.8.2.1
192.168.1.84 tracsrv.local - [10/Apr/2013:22:24:59 +0200] GET 
/git/foo.git/info/refs?service=git-receive-pack HTTP/1.1 401 351 - 
git/1.8.2.1
192.168.1.84 tracsrv.local magnus [10/Apr/2013:22:25:04 +0200] GET 
/git/foo.git/info/refs?service=git-receive-pack HTTP/1.1 200 202 - 
git/1.8.2.1
192.168.1.84 tracsrv.local magnus [10/Apr/2013:22:25:09 +0200] POST 
/git/foo.git/git-receive-pack HTTP/1.1 200 73 - git/1.8.2.1

That is, *both* the GET and POST queries require a valid username
(trying to push without a valid user will fail with a 403 already on
the GET query).  Maybe Apache 2.x simply behaves *very* differently
from lighttpd, but I still can't see how a rule to require a valid
user only on the POST can ever work.

 AFAICS this means the man-page is wrong, and that I instead ought
 to match on the service=git-receive-pack part.  Is that a correct
 conclusion?
 
 No. It is not a bad idea to _also_ match on info/refs, but I think
 it's a little trickier (you need to reliably match the query string
 to differentiate it from a fetch, which IIRC is a little hard in
 apache, at least).

This is what triggered me to find a working config.  Matching on the
query string is actually *very* easy in lighttpd.  Here's the relevant
bit of a working configuration[1]:

alias.url += ( /git = /usr/lib/git-core/git-http-backend )
$HTTP[querystring] =~ service=git-receive-pack {
$HTTP[url] =~ ^/git {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
include trac-git-auth.conf
}
} else $HTTP[url] =~ ^/git/.*/git-receive-pack$ {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
include trac-git-auth.conf
} else $HTTP[url] =~ ^/git {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
}

 But if you drop the protections on /git-receive-pack$, then an
 attacker can just POST whatever they want into your repository.

This setup is for a server on the internal network, but still, your
comment holds.  The reason for wanting to allow reading without
authentication is that then I can signal a CI server to pull without
having to give it credentials.

/M

[1]: The configuration for the authentication looks like this at the
moment, but it's only for testing:

auth.backend = plain
auth.backend.plain.userfile = /srv/git/pwds.plain
auth.require = (
/ = (
method = basic,
realm = git,
require = valid-user
)
)
-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4 
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus

Most

Re: git-http-backend: anonymous read, authenticated write

2013-04-10 Thread Magnus Therning
On Tue, Apr 09, 2013 at 02:24:26PM +0200, Jakub Narębski wrote:
 On 09.04.2013, Magnus Therning wrote:
 
  I've been trying to set up git-http-backend+lighttpd.  I've managed to
  set up anonymous read-only access, and I then successfully configured
  authentication for both read and write.  Then I get stuck.  The
  man-page for git-http-backend says that the following snippet can be
  used for Apache 2.x:
  
  LocationMatch ^/git/.*/git-receive-pack$
  AuthType Basic
  AuthName Git Access
  Require group committers
  ...
  /LocationMatch
  
  However, when I put in this match on location in my lighty config and
  try to push I'm not asked for a password, instead I'm greeted with
  
  % git push 
  error: The requested URL returned error: 403 Forbidden while 
   accessing
 http://magnus@tracsrv.local/git/foo.git/info/refs?service=git-receive-pack
  
  AFAICS this means the man-page is wrong, and that I instead ought to
  match on the service=git-receive-pack part.  Is that a correct
  conclusion?
 
 Yes, it is.
 
 I have tried to do the same anonymous read and authenticated write
 in smart HTTP access in Apache.  There are some proposals[1],
 all I think which use mod_rewrite (as LocationMatch doesn't take
 query string into account, unfortunately), but I haven't been able
 to make it work.
 
 The problem is that both POST *and GET* (to get refs) must be authethicated.
 
 Nb. I thought that it was corrected... which git version do you use?

1.8.2 on the server, though 1.8.2.1 is available for the distro I'm
using.  The discussion you refer to took place in 2010, I doubt any
improvement has been made to this in that point release, or am I
wrong?

 [1]: http://paperlined.org/apps/git/SmartHTTP_Ubuntu.html
 
 
 In the end I have worked around this by allowing all registered users to
 read with require valid-user (which in my situation might be even more
 correct solution; the case being repositories for Computer Science class
 lab work), and restricting write via pre-receive hook which checks
 REMOTE_USER.

I *really* want anonymous RO access so the CI server doesn't need any
credentials.  I could of course set up git-http-backend to be served
on two different URLs, but that's just ugly ;)

Luckily I did find a working configuration, which I posted in another
email in this thread.

/M

-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4 
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus


Perl is another example of filling a tiny, short-term need, and then
being a real problem in the longer term.
 -- Alan Kay


pgp6Iw96ionh4.pgp
Description: PGP signature


Re: git-http-backend: anonymous read, authenticated write

2013-04-10 Thread Magnus Therning
On Wed, Apr 10, 2013 at 05:47:22PM -0400, Jeff King wrote:
 On Wed, Apr 10, 2013 at 11:30:59PM +0200, Jakub Narębski wrote:
 
   1. GET $repo/info/refs?service=git-receive-pack
 
  This makes initial contact and gets the ref information which
  push uses to decide what it is going to push. So it is
  read-only, and in an anonymous-read setup, does not need to
  be protected.
 
 Yes, it doesn't need to be protected, but *git-receive-pack*
 requires (or required) valid user even for above GET request for
 getting refs.
 
 Right. But that is not anything receive-pack is doing; it is up to
 his webserver config, which is why I asked to see it.

Nope.  I'm pretty sure this had *nothing* to do with my config.  This
is the original config, which doesn't work:

$HTTP[url] =~ ^/git {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
$HTTP[url] =~ ^/git/.*/git-receive-pack$ {
include trac-git-auth.conf
}
}

This will turn on authentication *only* for URLs matching
^/git/.*/git-receive-pack$, which AFAIU is *exactly* what the manpage states is
all that is needed.

This is the configuration that actually works:

$HTTP[querystring] =~ service=git-receive-pack {
$HTTP[url] =~ ^/git {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
include trac-git-auth.conf
}
} else $HTTP[url] =~ ^/git {
cgi.assign = (  =  )
setenv.add-environment = (
GIT_PROJECT_ROOT = /srv/git,
GIT_HTTP_EXPORT_ALL = 
)
$HTTP[url] =~ ^/git/.*/git-receive-pack$ {
include trac-git-auth.conf
}
}

The top bit adds matching against the query string and ^/git which
forces authentication on the initial GET as well.

   2. POST $repo/git-receive-pack
 
  This actually pushes up the objects and updates the refs, and
  must be protected.
 
 The setup listed above does work with apache; it is tested as part
 of our test suite (you can see the actual config in
 t/lib-httpd/apache.conf).  So what in lighttpd is giving us the
 403? Can you share your whole config?
 
 I think I have seen a patch on git mailing list to correct this,
 but I am not sure.
 
 Are you sure that we test this correctly?
 
 Perhaps you are thinking of the jk/maint-http-half-auth-push topic
 from last August/September. It explicitly tests the setup from the
 manpage.  The relevant commits are 4c71009 (t: test http access to
 half-auth repositories, 2012-08-27) which demonstrates the
 problem, and b81401c (http: prompt for credentials on failed POST,
 2012-08-27).
 
 However, even before the fix, it never got a 403 on the GET of
 info/refs. It got a 401 on the later POST, but didn't prompt for
 credentials.

I know nothing about CGI, but surely the script signals the need for a
valid user to the server somehow, couldn't the web server then decide
to return 403 rather than 401 *if there's no configuration for
authentication*?

In any case it seems there is no fix in the version of git in Arch
Linux[1].

/M

[1]: The package I've been using is built from these unpatched
sources: http://git-core.googlecode.com/files/git-1.8.2.tar.gz

-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4 
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus

I invented the term Object-Oriented, and I can tell you I did not have
C++ in mind.
 -- Alan Kay


pgpahfEucblbu.pgp
Description: PGP signature


git-http-backend: anonymous read, authenticated write

2013-04-08 Thread Magnus Therning
I've been trying to set up git-http-backend+lighttpd.  I've managed to
set up anonymous read-only access, and I then successfully configured
authentication for both read and write.  Then I get stuck.  The
man-page for git-http-backend says that the following snippet can be
used for Apache 2.x:

LocationMatch ^/git/.*/git-receive-pack$
AuthType Basic
AuthName Git Access
Require group committers
...
/LocationMatch

However, when I put in this match on location in my lighty config and
try to push I'm not asked for a password, instead I'm greeted with

% git push 
error: The requested URL returned error: 403 Forbidden while accessing 
http://magnus@tracsrv.local/git/foo.git/info/refs?service=git-receive-pack

AFAICS this means the man-page is wrong, and that I instead ought to
match on the service=git-receive-pack part.  Is that a correct
conclusion?

/M

-- 
Magnus Therning  OpenPGP: 0xAB4DFBA4 
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus

I invented the term Object-Oriented, and I can tell you I did not have
C++ in mind.
 -- Alan Kay


pgpFgtZeHEfJz.pgp
Description: PGP signature