Skip to content

Commit 37417b7

Browse files
bk2204gitster
authored andcommitted
t5563: refactor for multi-stage authentication
Some HTTP authentication schemes, such as NTLM- and Kerberos-based options, require more than one round trip to authenticate. Currently, these can only be supported in libcurl, since Git does not have support for this in the credential helper protocol. However, in a future commit, we'll add support for this functionality into the credential helper protocol and Git itself. Because we don't really want to implement either NTLM or Kerberos, both of which are complex protocols, we'll want to test this using a fake credential authentication scheme. In order to do so, update t5563 and its backend to allow us to accept multiple sets of credentials and respond with different behavior in each case. Since we can now provide any number of possible status codes, provide a non-specific reason phrase so we don't have to generate a more specific one based on the response. The reason phrase is mandatory according to the status-line production in RFC 7230, but clients SHOULD ignore it, and curl does (except to print it). Each entry in the authorization and challenge fields contains an ID, which indicates a corresponding credential and response. If the response is a 200 status, then we continue to execute git-http-backend. Otherwise, we print the corresponding status and response. If no ID is matched, we use the default response with a status of 401. Note that there is an implicit order to the parameters. The ID is always first and the creds or response value is always last, and therefore may contain spaces, equals signs, or other arbitrary data. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bd590bd commit 37417b7

File tree

2 files changed

+66
-47
lines changed

2 files changed

+66
-47
lines changed

t/lib-httpd/nph-custom-auth.sh

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,30 @@ CHALLENGE_FILE=custom-auth.challenge
1919
#
2020

2121
if test -n "$HTTP_AUTHORIZATION" && \
22-
grep -Fqsx "${HTTP_AUTHORIZATION}" "$VALID_CREDS_FILE"
22+
grep -Fqs "creds=${HTTP_AUTHORIZATION}" "$VALID_CREDS_FILE"
2323
then
24+
idno=$(grep -F "creds=${HTTP_AUTHORIZATION}" "$VALID_CREDS_FILE" | sed -e 's/^id=\([a-z0-9-][a-z0-9-]*\) .*$/\1/')
25+
status=$(sed -ne "s/^id=$idno.*status=\\([0-9][0-9][0-9]\\).*\$/\\1/p" "$CHALLENGE_FILE" | head -n1)
2426
# Note that although git-http-backend returns a status line, it
2527
# does so using a CGI 'Status' header. Because this script is an
2628
# No Parsed Headers (NPH) script, we must return a real HTTP
2729
# status line.
2830
# This is only a test script, so we don't bother to check for
2931
# the actual status from git-http-backend and always return 200.
30-
echo 'HTTP/1.1 200 OK'
31-
exec "$GIT_EXEC_PATH"/git-http-backend
32+
echo "HTTP/1.1 $status Nonspecific Reason Phrase"
33+
if test "$status" -eq 200
34+
then
35+
exec "$GIT_EXEC_PATH"/git-http-backend
36+
else
37+
sed -ne "s/^id=$idno.*response=//p" "$CHALLENGE_FILE"
38+
echo
39+
exit
40+
fi
3241
fi
3342

3443
echo 'HTTP/1.1 401 Authorization Required'
3544
if test -f "$CHALLENGE_FILE"
3645
then
37-
cat "$CHALLENGE_FILE"
46+
sed -ne 's/^id=default.*response=//p' "$CHALLENGE_FILE"
3847
fi
3948
echo

t/t5563-simple-http-auth.sh

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ test_expect_success 'access using basic auth' '
6363
6464
# Basic base64(alice:secret-passwd)
6565
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
66-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
66+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
6767
EOF
6868
6969
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
70-
WWW-Authenticate: Basic realm="example.com"
70+
id=1 status=200
71+
id=default response=WWW-Authenticate: Basic realm="example.com"
7172
EOF
7273
7374
test_config_global credential.helper test-helper &&
@@ -100,11 +101,12 @@ test_expect_success 'access using basic auth via authtype' '
100101
101102
# Basic base64(alice:secret-passwd)
102103
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
103-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
104+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
104105
EOF
105106
106107
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
107-
WWW-Authenticate: Basic realm="example.com"
108+
id=1 status=200
109+
id=default response=WWW-Authenticate: Basic realm="example.com"
108110
EOF
109111
110112
test_config_global credential.helper test-helper &&
@@ -137,11 +139,12 @@ test_expect_success 'access using basic auth invalid credentials' '
137139
138140
# Basic base64(alice:secret-passwd)
139141
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
140-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
142+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
141143
EOF
142144
143145
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
144-
WWW-Authenticate: Basic realm="example.com"
146+
id=1 status=200
147+
id=default response=WWW-Authenticate: Basic realm="example.com"
145148
EOF
146149
147150
test_config_global credential.helper test-helper &&
@@ -174,13 +177,14 @@ test_expect_success 'access using basic auth with extra challenges' '
174177
175178
# Basic base64(alice:secret-passwd)
176179
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
177-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
180+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
178181
EOF
179182
180183
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
181-
WWW-Authenticate: FooBar param1="value1" param2="value2"
182-
WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
183-
WWW-Authenticate: Basic realm="example.com"
184+
id=1 status=200
185+
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
186+
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
187+
id=default response=WWW-Authenticate: Basic realm="example.com"
184188
EOF
185189
186190
test_config_global credential.helper test-helper &&
@@ -214,13 +218,14 @@ test_expect_success 'access using basic auth mixed-case wwwauth header name' '
214218
215219
# Basic base64(alice:secret-passwd)
216220
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
217-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
221+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
218222
EOF
219223
220224
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
221-
www-authenticate: foobar param1="value1" param2="value2"
222-
WWW-AUTHENTICATE: BEARER authorize_uri="id.example.com" p=1 q=0
223-
WwW-aUtHeNtIcAtE: baSiC realm="example.com"
225+
id=1 status=200
226+
id=default response=www-authenticate: foobar param1="value1" param2="value2"
227+
id=default response=WWW-AUTHENTICATE: BEARER authorize_uri="id.example.com" p=1 q=0
228+
id=default response=WwW-aUtHeNtIcAtE: baSiC realm="example.com"
224229
EOF
225230
226231
test_config_global credential.helper test-helper &&
@@ -254,18 +259,19 @@ test_expect_success 'access using basic auth with wwwauth header continuations'
254259
255260
# Basic base64(alice:secret-passwd)
256261
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
257-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
262+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
258263
EOF
259264
260265
# Note that leading and trailing whitespace is important to correctly
261266
# simulate a continuation/folded header.
262267
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
263-
WWW-Authenticate: FooBar param1="value1"
264-
param2="value2"
265-
WWW-Authenticate: Bearer authorize_uri="id.example.com"
266-
p=1
267-
q=0
268-
WWW-Authenticate: Basic realm="example.com"
268+
id=1 status=200
269+
id=default response=WWW-Authenticate: FooBar param1="value1"
270+
id=default response= param2="value2"
271+
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com"
272+
id=default response= p=1
273+
id=default response= q=0
274+
id=default response=WWW-Authenticate: Basic realm="example.com"
269275
EOF
270276
271277
test_config_global credential.helper test-helper &&
@@ -299,21 +305,22 @@ test_expect_success 'access using basic auth with wwwauth header empty continuat
299305
300306
# Basic base64(alice:secret-passwd)
301307
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
302-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
308+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
303309
EOF
304310
305311
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
306312
307313
# Note that leading and trailing whitespace is important to correctly
308314
# simulate a continuation/folded header.
309-
printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >"$CHALLENGE" &&
310-
printf " \r\n" >>"$CHALLENGE" &&
311-
printf " param2=\"value2\"\r\n" >>"$CHALLENGE" &&
312-
printf "WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>"$CHALLENGE" &&
313-
printf " p=1\r\n" >>"$CHALLENGE" &&
314-
printf " \r\n" >>"$CHALLENGE" &&
315-
printf " q=0\r\n" >>"$CHALLENGE" &&
316-
printf "WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" &&
315+
printf "id=1 status=200\n" >"$CHALLENGE" &&
316+
printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
317+
printf "id=default response= \r\n" >>"$CHALLENGE" &&
318+
printf "id=default response= param2=\"value2\"\r\n" >>"$CHALLENGE" &&
319+
printf "id=default response=WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>"$CHALLENGE" &&
320+
printf "id=default response= p=1\r\n" >>"$CHALLENGE" &&
321+
printf "id=default response= \r\n" >>"$CHALLENGE" &&
322+
printf "id=default response= q=0\r\n" >>"$CHALLENGE" &&
323+
printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" &&
317324
318325
test_config_global credential.helper test-helper &&
319326
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
@@ -346,17 +353,18 @@ test_expect_success 'access using basic auth with wwwauth header mixed line-endi
346353
347354
# Basic base64(alice:secret-passwd)
348355
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
349-
Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
356+
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
350357
EOF
351358
352359
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
353360
354361
# Note that leading and trailing whitespace is important to correctly
355362
# simulate a continuation/folded header.
356-
printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >"$CHALLENGE" &&
357-
printf " \r\n" >>"$CHALLENGE" &&
358-
printf "\tparam2=\"value2\"\r\n" >>"$CHALLENGE" &&
359-
printf "WWW-Authenticate: Basic realm=\"example.com\"" >>"$CHALLENGE" &&
363+
printf "id=1 status=200\n" >"$CHALLENGE" &&
364+
printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
365+
printf "id=default response= \r\n" >>"$CHALLENGE" &&
366+
printf "id=default response=\tparam2=\"value2\"\r\n" >>"$CHALLENGE" &&
367+
printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"" >>"$CHALLENGE" &&
360368
361369
test_config_global credential.helper test-helper &&
362370
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
@@ -389,15 +397,16 @@ test_expect_success 'access using bearer auth' '
389397
390398
# Basic base64(a-git-token)
391399
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
392-
Bearer YS1naXQtdG9rZW4=
400+
id=1 creds=Bearer YS1naXQtdG9rZW4=
393401
EOF
394402
395403
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
396404
397405
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
398-
WWW-Authenticate: FooBar param1="value1" param2="value2"
399-
WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
400-
WWW-Authenticate: Basic realm="example.com"
406+
id=1 status=200
407+
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
408+
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
409+
id=default response=WWW-Authenticate: Basic realm="example.com"
401410
EOF
402411
403412
test_config_global credential.helper test-helper &&
@@ -433,15 +442,16 @@ test_expect_success 'access using bearer auth with invalid credentials' '
433442
434443
# Basic base64(a-git-token)
435444
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
436-
Bearer YS1naXQtdG9rZW4=
445+
id=1 creds=Bearer YS1naXQtdG9rZW4=
437446
EOF
438447
439448
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
440449
441450
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
442-
WWW-Authenticate: FooBar param1="value1" param2="value2"
443-
WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
444-
WWW-Authenticate: Basic realm="example.com"
451+
id=1 status=200
452+
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
453+
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
454+
id=default response=WWW-Authenticate: Basic realm="example.com"
445455
EOF
446456
447457
test_config_global credential.helper test-helper &&

0 commit comments

Comments
 (0)