Skip to content

Commit 56303b8

Browse files
committed
Merge branch 'jk/doc-http-backend' into maint
Improve documentation to illustrate "push authenticated, fetch anonymous" configuration for smart HTTP servers. * jk/doc-http-backend: doc/http-backend: match query-string in apache half-auth example doc/http-backend: give some lighttpd config examples doc/http-backend: clarify "half-auth" repo configuration
2 parents ac85caa + b080881 commit 56303b8

File tree

3 files changed

+129
-1
lines changed

3 files changed

+129
-1
lines changed

Documentation/git-http-backend.txt

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,30 @@ ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
8080
----------------------------------------------------------------
8181
+
8282
To enable anonymous read access but authenticated write access,
83-
require authorization with a LocationMatch directive:
83+
require authorization for both the initial ref advertisement (which we
84+
detect as a push via the service parameter in the query string), and the
85+
receive-pack invocation itself:
86+
+
87+
----------------------------------------------------------------
88+
RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
89+
RewriteCond %{REQUEST_URI} /git-receive-pack$
90+
RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]
91+
92+
<LocationMatch "^/git/">
93+
Order Deny,Allow
94+
Deny from env=AUTHREQUIRED
95+
96+
AuthType Basic
97+
AuthName "Git Access"
98+
Require group committers
99+
Satisfy Any
100+
...
101+
</LocationMatch>
102+
----------------------------------------------------------------
103+
+
104+
If you do not have `mod_rewrite` available to match against the query
105+
string, it is sufficient to just protect `git-receive-pack` itself,
106+
like:
84107
+
85108
----------------------------------------------------------------
86109
<LocationMatch "^/git/.*/git-receive-pack$">
@@ -91,6 +114,15 @@ require authorization with a LocationMatch directive:
91114
</LocationMatch>
92115
----------------------------------------------------------------
93116
+
117+
In this mode, the server will not request authentication until the
118+
client actually starts the object negotiation phase of the push, rather
119+
than during the initial contact. For this reason, you must also enable
120+
the `http.receivepack` config option in any repositories that should
121+
accept a push. The default behavior, if `http.receivepack` is not set,
122+
is to reject any pushes by unauthenticated users; the initial request
123+
will therefore report `403 Forbidden` to the client, without even giving
124+
an opportunity for authentication.
125+
+
94126
To require authentication for both reads and writes, use a Location
95127
directive around the repository, or one of its parent directories:
96128
+
@@ -158,6 +190,54 @@ ScriptAliasMatch \
158190
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
159191
----------------------------------------------------------------
160192

193+
Lighttpd::
194+
Ensure that `mod_cgi`, `mod_alias, `mod_auth`, `mod_setenv` are
195+
loaded, then set `GIT_PROJECT_ROOT` appropriately and redirect
196+
all requests to the CGI:
197+
+
198+
----------------------------------------------------------------
199+
alias.url += ( "/git" => "/usr/lib/git-core/git-http-backend" )
200+
$HTTP["url"] =~ "^/git" {
201+
cgi.assign = ("" => "")
202+
setenv.add-environment = (
203+
"GIT_PROJECT_ROOT" => "/var/www/git",
204+
"GIT_HTTP_EXPORT_ALL" => ""
205+
)
206+
}
207+
----------------------------------------------------------------
208+
+
209+
To enable anonymous read access but authenticated write access:
210+
+
211+
----------------------------------------------------------------
212+
$HTTP["querystring"] =~ "service=git-receive-pack" {
213+
include "git-auth.conf"
214+
}
215+
$HTTP["url"] =~ "^/git/.*/git-receive-pack$" {
216+
include "git-auth.conf"
217+
}
218+
----------------------------------------------------------------
219+
+
220+
where `git-auth.conf` looks something like:
221+
+
222+
----------------------------------------------------------------
223+
auth.require = (
224+
"/" => (
225+
"method" => "basic",
226+
"realm" => "Git Access",
227+
"require" => "valid-user"
228+
)
229+
)
230+
# ...and set up auth.backend here
231+
----------------------------------------------------------------
232+
+
233+
To require authentication for both reads and writes:
234+
+
235+
----------------------------------------------------------------
236+
$HTTP["url"] =~ "^/git/private" {
237+
include "git-auth.conf"
238+
}
239+
----------------------------------------------------------------
240+
161241

162242
ENVIRONMENT
163243
-----------

t/lib-httpd/apache.conf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ ErrorLog error.log
4040
<IfModule !mod_authz_user.c>
4141
LoadModule authz_user_module modules/mod_authz_user.so
4242
</IfModule>
43+
<IfModule !mod_authz_host.c>
44+
LoadModule authz_host_module modules/mod_authz_host.so
45+
</IfModule>
4346
</IfVersion>
4447

4548
PassEnv GIT_VALGRIND
@@ -110,6 +113,21 @@ SSLEngine On
110113
Require valid-user
111114
</LocationMatch>
112115

116+
RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
117+
RewriteCond %{REQUEST_URI} /git-receive-pack$
118+
RewriteRule ^/half-auth-complete/ - [E=AUTHREQUIRED:yes]
119+
120+
<Location /half-auth-complete/>
121+
Order Deny,Allow
122+
Deny from env=AUTHREQUIRED
123+
124+
AuthType Basic
125+
AuthName "Git Access"
126+
AuthUserFile passwd
127+
Require valid-user
128+
Satisfy Any
129+
</Location>
130+
113131
<IfDefine DAV>
114132
LoadModule dav_module modules/mod_dav.so
115133
LoadModule dav_fs_module modules/mod_dav_fs.so

t/t5541-http-push.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,5 +295,35 @@ test_expect_success 'push to auth-only-for-push repo' '
295295
test_cmp expect actual
296296
'
297297

298+
test_expect_success 'create repo without http.receivepack set' '
299+
cd "$ROOT_PATH" &&
300+
git init half-auth &&
301+
(
302+
cd half-auth &&
303+
test_commit one
304+
) &&
305+
git clone --bare half-auth "$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git"
306+
'
307+
308+
test_expect_success 'clone via half-auth-complete does not need password' '
309+
cd "$ROOT_PATH" &&
310+
set_askpass wrong &&
311+
git clone "$HTTPD_URL"/half-auth-complete/smart/half-auth.git \
312+
half-auth-clone &&
313+
expect_askpass none
314+
'
315+
316+
test_expect_success 'push into half-auth-complete requires password' '
317+
cd "$ROOT_PATH/half-auth-clone" &&
318+
echo two >expect &&
319+
test_commit two &&
320+
set_askpass user@host &&
321+
git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
322+
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
323+
log -1 --format=%s >actual &&
324+
expect_askpass both user@host &&
325+
test_cmp expect actual
326+
'
327+
298328
stop_httpd
299329
test_done

0 commit comments

Comments
 (0)