threads / discuss / 22967

git-http-backend and Authenticated Pushes

Subject: git-http-backend and Authenticated Pushes

## tl;dr

6 messages between Mar 9, 2010 and Mar 10, 2010.

replies: 5people: 4as markdown or json

Ryan Phillips· Mar 9, 2010, 17:08 UTC · lore
Hi All,

I'm trying to follow the git-http-backend man page on setting up authenticated pushes to my apache server. Pulls work fine, and fully authenticated pushes work fine. However, when I try and setup anonymous pulls and authenticated pushes the push fails.

I believe the culprit is this 403 error:

192.168.1.1 - - [09/Mar/2010:09:01:43 -0800] "GET /git/test.git/info/refs?service=git-receive-pack HTTP/1.1" 403 - "-" "git/1.7.0.2.dirty"

Anybody know what I missed?

Regards, Ryan

My vhost replaced with example.com:
<VirtualHost *:80>
        SetEnv GIT_PROJECT_ROOT /home/httpd/domains/example.com/repo
        SetEnv GIT_HTTP_EXPORT_ALL
        SetEnv GITWEB_CONFIG /home/httpd/domains/example.com/gitweb.conf
        RewriteEngine on
        RewriteRule ^/$     /git/ [PT]
        <Directory /usr/local/git>
           Options Indexes FollowSymLinks MultiViews Includes ExecCGI
           AllowOverride None
           Order allow,deny
           Allow from all
        </Directory>
        <LocationMatch "^/git/.*/git-receive-pack$">
            AuthType Basic
            AuthName "Git Access"
            AuthUserFile /home/httpd/domains/example.com/.htpasswd
            Require valid-user
        </LocationMatch>
        ScriptAliasMatch \
                "(?x)^/git/(.*/(HEAD | \
                                info/refs | \
                                objects/(info/[^/]+ | \
                                         [0-9a-f]{2}/[0-9a-f]{38} | \
                                         pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                                git-(upload|receive)-pack))$" \
                /usr/local/git/current/libexec/git-core/git-http-backend/$1
        ScriptAlias /git/ /usr/local/git/current/gitweb/gitweb.cgi/
        Alias       /gitweb.css       /usr/local/git/current/gitweb/gitweb.css
        Alias       /git-logo.png     /usr/local/git/current/gitweb/git-logo.png
        Alias       /git-favicon.png
/usr/local/git/current/gitweb/git-favicon.png
        ServerName example.com
        ServerAlias *.example.com
        ErrorLog /home/httpd/domains/example.com/logs/error_log
        CustomLog /home/httpd/domains/example.com/logs/access_log combined
</VirtualHost>
Antonio García Domínguez· Mar 9, 2010, 19:01 UTC · re: Ryan Phillips · lore

Re: git-http-backend and Authenticated Pushes

Hi Ryan,
> Anybody know what I missed?

I think you need authentication for everything regarding git-receive-pack, even that GET request. I ran into that issue while patching Redmine's mod-perl authentication module to handle smart HTTP [1]. Public projects (which have anonymous pull and authenticated push) would just not work.

Git first GETs that URL you mention, and then POSTs to the usual git-receive-pack URL. Both need authentication, but you're only authenticating the POST. I suggest you authenticate every request to the git-receive-pack service. Try something like this (warning, untested!):

>        <LocationMatch "^/git/.*/[^/]*git-receive-pack$">
If anyone else has a better idea, I'd like to know myself :-).
[1]: http://www.redmine.org/issues/4905

Cheers, Antonio

BJ Hargrave· Mar 9, 2010, 19:17 UTC · re: Antonio García Domínguez · lore

Re: git-http-backend and Authenticated Pushes

On Mar 9, 2010, at 14:01 , Antonio García Domínguez wrote:
Show 7 quoted lines
> Git first GETs that URL you mention, and then POSTs to the usual
> git-receive-pack URL. Both need authentication, but you're only
> authenticating the POST. I suggest you authenticate every request to
> the git-receive-pack service. Try something like this (warning,
> untested!):
> 
>>       <LocationMatch "^/git/.*/[^/]*git-receive-pack$"
LocationMatch will not match against the query string which is where the service name is. To match against the query string, you would need to do something like:
	RewriteCond %{QUERY_STRING} service=git-receive-pack
	RewriteRule .* - [E=AUTHREQUIRED:yes]
then
	Order Allow,Deny
	Deny from env=AUTHREQUIRED
	Allow from all
	Satisfy Any
	# Add other auth statements for password file.
(also untested :-)
But, I would think using <LimitExcept GET PROPFIND OPTIONS REPORT> to protect against "writing" to the repo without auth should be sufficient.
-- 
BJ Hargrave
Antonio García Domínguez· Mar 9, 2010, 19:23 UTC · re: BJ Hargrave · lore

Re: git-http-backend and Authenticated Pushes

Hi BJ,
> LocationMatch will not match against the query string which is where the service name is. To match against the query string, you would need to do something like:

Oops, you're right. I'm actually matching the unparsed URL using a regexp in a Perl authentication module, so I missed that Apache detail. Your snippet looks good to me.

> But, I would think using <LimitExcept GET PROPFIND OPTIONS REPORT> to protect against "writing" to the repo without auth should be sufficient.

But that doesn't work for the smart HTTP method. Limiting by method is OK for dumb HTTP (as we're basically just modifying files using WebDAV), but the git-http-backend CGI only uses GET and POST, and requires authentication depending not on the HTTP method, but what service is being used.

Or so I think :-).

Cheers, Antonio

Shawn O. Pearce· Mar 9, 2010, 19:27 UTC · re: Ryan Phillips · lore

Re: git-http-backend and Authenticated Pushes

Ryan Phillips <ryan@trolocsis.com> wrote:
Show 10 quoted lines
> I'm trying to follow the git-http-backend man page on setting up
> authenticated pushes to my apache server. Pulls work fine, and fully
> authenticated pushes work fine. However, when I try and setup
> anonymous pulls and authenticated pushes the push fails.
> 
> I believe the culprit is this 403 error:
> 
> 192.168.1.1 - - [09/Mar/2010:09:01:43 -0800] "GET
> /git/test.git/info/refs?service=git-receive-pack HTTP/1.1" 403 - "-"
> "git/1.7.0.2.dirty"
Ugh.  Looks like I didn't design this thing right.

The backend wants you to be authenticated before it will service the git-receive-pack advertisement. Even though its the same data as the git-upload-pack advertisement (but slightly different capability strings).

Maybe we should consider doing something like this patch so that the advertisement under info/refs?service=git-receive-pack can be sent without needing authentication. My only hesitation is this makes it harder for the client to setup the authentication before it needs to transmit the pack file, which may mean it needs to send the pack twice.

diff --git a/http-backend.c b/http-backend.c
index 345c12b..462b07c 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -312,11 +312,6 @@ static struct rpc_service *select_service(const char *name)
 
 	if (!svc)
 		forbidden("Unsupported service: '%s'", name);
-
-	if (svc->enabled < 0) {
-		const char *user = getenv("REMOTE_USER");
-		svc->enabled = (user && *user) ? 1 : 0;
-	}
 	if (!svc->enabled)
 		forbidden("Service not enabled: '%s'", svc->name);
 	return svc;
@@ -519,6 +514,12 @@ static void service_rpc(char *service_name)
 	struct rpc_service *svc = select_service(service_name);
 	struct strbuf buf = STRBUF_INIT;
 
+	if (svc->enabled < 0) {
+		const char *user = getenv("REMOTE_USER");
+		if (!user || !*user)
+			forbidden("Service not enabled: '%s'", svc->name);
+	}
+
 	strbuf_reset(&buf);
 	strbuf_addf(&buf, "application/x-git-%s-request", svc->name);
 	check_content_type(buf.buf);
 
-- 
Shawn.
Ryan Phillips· Mar 10, 2010, 02:13 UTC · re: Shawn O. Pearce · lore

Re: git-http-backend and Authenticated Pushes

On Tue, Mar 9, 2010 at 1:27 PM, Shawn O. Pearce <spearce@spearce.org> wrote:
Show 26 quoted lines
> Ryan Phillips <ryan@trolocsis.com> wrote:
>> I'm trying to follow the git-http-backend man page on setting up
>> authenticated pushes to my apache server. Pulls work fine, and fully
>> authenticated pushes work fine. However, when I try and setup
>> anonymous pulls and authenticated pushes the push fails.
>>
>> I believe the culprit is this 403 error:
>>
>> 192.168.1.1 - - [09/Mar/2010:09:01:43 -0800] "GET
>> /git/test.git/info/refs?service=git-receive-pack HTTP/1.1" 403 - "-"
>> "git/1.7.0.2.dirty"
>
> Ugh.  Looks like I didn't design this thing right.
>
> The backend wants you to be authenticated before it will service
> the git-receive-pack advertisement.  Even though its the same
> data as the git-upload-pack advertisement (but slightly different
> capability strings).
>
> Maybe we should consider doing something like this patch so that
> the advertisement under info/refs?service=git-receive-pack can be
> sent without needing authentication.  My only hesitation is this
> makes it harder for the client to setup the authentication before
> it needs to transmit the pack file, which may mean it needs to send
> the pack twice.
>
Thank you everyone for your response.
Shawn: That patch does fix the issue for now.

Regards, Ryan

← back to recent threads