2020-03-26 08:25:27 +00:00
|
|
|
# Shell library for testing credential handling including helpers. See t0302
|
|
|
|
# for an example of testing a specific helper.
|
2011-12-10 10:31:11 +00:00
|
|
|
|
|
|
|
# Try a set of credential helpers; the expected stdin,
|
|
|
|
# stdout and stderr should be provided on stdin,
|
|
|
|
# separated by "--".
|
|
|
|
check() {
|
2012-06-24 11:39:59 +00:00
|
|
|
credential_opts=
|
|
|
|
credential_cmd=$1
|
|
|
|
shift
|
|
|
|
for arg in "$@"; do
|
|
|
|
credential_opts="$credential_opts -c credential.helper='$arg'"
|
|
|
|
done
|
2011-12-10 10:31:11 +00:00
|
|
|
read_chunk >stdin &&
|
|
|
|
read_chunk >expect-stdout &&
|
|
|
|
read_chunk >expect-stderr &&
|
2012-06-24 11:39:59 +00:00
|
|
|
if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
|
|
|
|
echo "git credential failed with code $?" &&
|
|
|
|
cat stderr &&
|
|
|
|
false
|
|
|
|
fi &&
|
2011-12-10 10:31:11 +00:00
|
|
|
test_cmp expect-stdout stdout &&
|
2021-02-11 01:53:53 +00:00
|
|
|
test_cmp expect-stderr stderr
|
2011-12-10 10:31:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
read_chunk() {
|
|
|
|
while read line; do
|
|
|
|
case "$line" in
|
|
|
|
--) break ;;
|
|
|
|
*) echo "$line" ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2011-12-10 10:34:14 +00:00
|
|
|
# Clear any residual data from previous tests. We only
|
|
|
|
# need this when testing third-party helpers which read and
|
|
|
|
# write outside of our trash-directory sandbox.
|
|
|
|
#
|
|
|
|
# Don't bother checking for success here, as it is
|
|
|
|
# outside the scope of tests and represents a best effort to
|
|
|
|
# clean up after ourselves.
|
|
|
|
helper_test_clean() {
|
|
|
|
reject $1 https example.com store-user
|
|
|
|
reject $1 https example.com user1
|
|
|
|
reject $1 https example.com user2
|
2023-06-16 19:55:06 +00:00
|
|
|
reject $1 https example.com user-expiry
|
|
|
|
reject $1 https example.com user-expiry-overwrite
|
2023-04-21 09:47:59 +00:00
|
|
|
reject $1 https example.com user4
|
2023-06-15 19:19:32 +00:00
|
|
|
reject $1 https example.com user-distinct-pass
|
|
|
|
reject $1 https example.com user-overwrite
|
2023-06-15 19:19:33 +00:00
|
|
|
reject $1 https example.com user-erase1
|
|
|
|
reject $1 https example.com user-erase2
|
2024-02-15 01:03:56 +00:00
|
|
|
reject $1 https victim.example.com user
|
2011-12-10 10:34:14 +00:00
|
|
|
reject $1 http path.tld user
|
|
|
|
reject $1 https timeout.tld user
|
2017-10-30 17:20:12 +00:00
|
|
|
reject $1 https sso.tld
|
2011-12-10 10:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
reject() {
|
|
|
|
(
|
|
|
|
echo protocol=$2
|
|
|
|
echo host=$3
|
|
|
|
echo username=$4
|
2012-06-24 11:39:59 +00:00
|
|
|
) | git -c credential.helper=$1 credential reject
|
2011-12-10 10:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
helper_test() {
|
|
|
|
HELPER=$1
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) has no existing data" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) stores password" '
|
|
|
|
check approve $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=store-user
|
|
|
|
password=store-pass
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) can retrieve password" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=store-user
|
|
|
|
password=store-pass
|
|
|
|
--
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) requires matching protocol" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=http
|
|
|
|
host=example.com
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=http
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''http://example.com'\'':
|
|
|
|
askpass: Password for '\''http://askpass-username@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) requires matching host" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=other.tld
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=other.tld
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://other.tld'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@other.tld'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) requires matching username" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=other
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=other
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Password for '\''https://other@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) requires matching path" '
|
|
|
|
test_config credential.usehttppath true &&
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=http
|
|
|
|
host=path.tld
|
|
|
|
path=foo.git
|
|
|
|
username=user
|
|
|
|
password=pass
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=http
|
|
|
|
host=path.tld
|
|
|
|
path=bar.git
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=http
|
|
|
|
host=path.tld
|
|
|
|
path=bar.git
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''http://path.tld/bar.git'\'':
|
|
|
|
askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2023-06-15 19:19:32 +00:00
|
|
|
test_expect_success "helper ($HELPER) overwrites on store" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-overwrite
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Password for '\''https://user-overwrite@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2011-12-10 10:34:14 +00:00
|
|
|
test_expect_success "helper ($HELPER) can forget host" '
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) can store multiple users" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user1
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user2
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user1
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=user1
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user2
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=user2
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2023-06-15 19:19:32 +00:00
|
|
|
test_expect_success "helper ($HELPER) does not erase a password distinct from input" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-distinct-pass
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-distinct-pass
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-distinct-pass
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-distinct-pass
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2011-12-10 10:34:14 +00:00
|
|
|
test_expect_success "helper ($HELPER) can forget user" '
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user1
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user1
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=user1
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Password for '\''https://user1@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) remembers other user" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user2
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=example.com
|
2011-12-10 10:34:14 +00:00
|
|
|
username=user2
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
'
|
2017-10-30 17:20:12 +00:00
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) can store empty username" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=sso.tld
|
|
|
|
username=
|
|
|
|
password=
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=sso.tld
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=sso.tld
|
|
|
|
username=
|
|
|
|
password=
|
|
|
|
EOF
|
|
|
|
'
|
t/lib-credential.sh: ensure credential helpers handle long headers
Add a test ensuring that the "wwwauth[]" field cannot be used to
inject malicious data into the credential helper stream.
Many of the credential helpers in contrib/credential read the
newline-delimited protocol stream one line at a time by repeatedly
calling fgets() into a fixed-size buffer.
This assumes that each line is no more than 1024 characters long, since
each iteration of the loop assumes that it is parsing starting at the
beginning of a new line in the stream. However, similar to a5bb10fd5e
(config: avoid fixed-sized buffer when renaming/deleting a section,
2023-04-06), if a line is longer than 1024 characters, a malicious actor
can embed another command within an existing line, bypassing the usual
checks introduced in 9a6bbee800 (credential: avoid writing values with
newlines, 2020-03-11).
As with the problem fixed in that commit, specially crafted input can
cause the helper to return the credential for the wrong host, letting an
attacker trick the victim into sending credentials for one host to
another.
Luckily, all parts of the credential helper protocol that are available
in a tagged release of Git are immune to this attack:
- "protocol" is restricted to known values, and is thus immune.
- "host" is immune because curl will reject hostnames that have a '='
character in them, which would be required to carry out this attack.
- "username" is immune, because the buffer characters to fill out the
first `fgets()` call would pollute the `username` field, causing the
credential helper to return nothing (because it would match a
username if present, and the username of the credential to be stolen
is likely not 1024 characters).
- "password" is immune because providing a password instructs
credential helpers to avoid filling credentials in the first place.
- "path" is similar to username; if present, it is not likely to match
any credential the victim is storing. It's also not enabled by
default; the victim would have to set credential.useHTTPPath
explicitly.
However, the new "wwwauth[]" field introduced via 5f2117b24f
(credential: add WWW-Authenticate header to cred requests, 2023-02-27)
can be used to inject data into the credential helper stream. For
example, running:
{
printf 'HTTP/1.1 401\r\n'
printf 'WWW-Authenticate: basic realm='
perl -e 'print "a" x 1024'
printf 'host=victim.com\r\n'
} | nc -Nlp 8080
in one terminal, and then:
git clone http://localhost:8080
in another would result in a line like:
wwwauth[]=basic realm=aaa[...]aaahost=victim.com
being sent to the credential helper. If we tweak that "1024" to align
our output with the helper's buffer size and the rest of the data on the
line, it can cause the helper to see "host=victim.com" on its own line,
allowing motivated attackers to exfiltrate credentials belonging to
"victim.com".
The below test demonstrates these failures and provides us with a test
to ensure that our fix is correct. That said, it has a couple of
shortcomings:
- it's in t0303, since that's the only mechanism we have for testing
random helpers. But that means nobody is going to run it under
normal circumstances.
- to get the attack right, it has to line up the stuffed name with the
buffer size, so we depend on the exact buffer size. I parameterized
it so it could be used to test other helpers, but in practice it's
not likely for anybody to do that.
Still, it's the best we can do, and will help us confirm the presence of
the problem (and our fixes) in the new few patches.
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-01 15:53:51 +00:00
|
|
|
|
2023-06-15 19:19:33 +00:00
|
|
|
test_expect_success "helper ($HELPER) erases all matching credentials" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-erase1
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-erase2
|
|
|
|
password=pass1
|
|
|
|
EOF
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
t/lib-credential.sh: ensure credential helpers handle long headers
Add a test ensuring that the "wwwauth[]" field cannot be used to
inject malicious data into the credential helper stream.
Many of the credential helpers in contrib/credential read the
newline-delimited protocol stream one line at a time by repeatedly
calling fgets() into a fixed-size buffer.
This assumes that each line is no more than 1024 characters long, since
each iteration of the loop assumes that it is parsing starting at the
beginning of a new line in the stream. However, similar to a5bb10fd5e
(config: avoid fixed-sized buffer when renaming/deleting a section,
2023-04-06), if a line is longer than 1024 characters, a malicious actor
can embed another command within an existing line, bypassing the usual
checks introduced in 9a6bbee800 (credential: avoid writing values with
newlines, 2020-03-11).
As with the problem fixed in that commit, specially crafted input can
cause the helper to return the credential for the wrong host, letting an
attacker trick the victim into sending credentials for one host to
another.
Luckily, all parts of the credential helper protocol that are available
in a tagged release of Git are immune to this attack:
- "protocol" is restricted to known values, and is thus immune.
- "host" is immune because curl will reject hostnames that have a '='
character in them, which would be required to carry out this attack.
- "username" is immune, because the buffer characters to fill out the
first `fgets()` call would pollute the `username` field, causing the
credential helper to return nothing (because it would match a
username if present, and the username of the credential to be stolen
is likely not 1024 characters).
- "password" is immune because providing a password instructs
credential helpers to avoid filling credentials in the first place.
- "path" is similar to username; if present, it is not likely to match
any credential the victim is storing. It's also not enabled by
default; the victim would have to set credential.useHTTPPath
explicitly.
However, the new "wwwauth[]" field introduced via 5f2117b24f
(credential: add WWW-Authenticate header to cred requests, 2023-02-27)
can be used to inject data into the credential helper stream. For
example, running:
{
printf 'HTTP/1.1 401\r\n'
printf 'WWW-Authenticate: basic realm='
perl -e 'print "a" x 1024'
printf 'host=victim.com\r\n'
} | nc -Nlp 8080
in one terminal, and then:
git clone http://localhost:8080
in another would result in a line like:
wwwauth[]=basic realm=aaa[...]aaahost=victim.com
being sent to the credential helper. If we tweak that "1024" to align
our output with the helper's buffer size and the rest of the data on the
line, it can cause the helper to see "host=victim.com" on its own line,
allowing motivated attackers to exfiltrate credentials belonging to
"victim.com".
The below test demonstrates these failures and provides us with a test
to ensure that our fix is correct. That said, it has a couple of
shortcomings:
- it's in t0303, since that's the only mechanism we have for testing
random helpers. But that means nobody is going to run it under
normal circumstances.
- to get the attack right, it has to line up the stuffed name with the
buffer size, so we depend on the exact buffer size. I parameterized
it so it could be used to test other helpers, but in practice it's
not likely for anybody to do that.
Still, it's the best we can do, and will help us confirm the presence of
the problem (and our fixes) in the new few patches.
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-01 15:53:51 +00:00
|
|
|
: ${GIT_TEST_LONG_CRED_BUFFER:=1024}
|
|
|
|
# 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL
|
|
|
|
LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23))
|
|
|
|
LONG_VALUE=$(perl -e 'print "a" x shift' $LONG_VALUE_LEN)
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) not confused by long header" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=victim.example.com
|
|
|
|
username=user
|
|
|
|
password=to-be-stolen
|
|
|
|
EOF
|
|
|
|
|
|
|
|
check fill $HELPER <<-EOF
|
|
|
|
protocol=https
|
|
|
|
host=badguy.example.com
|
|
|
|
wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=badguy.example.com
|
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://badguy.example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@badguy.example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
2011-12-10 10:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
helper_test_timeout() {
|
|
|
|
HELPER="$*"
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) times out" '
|
|
|
|
check approve "$HELPER" <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=timeout.tld
|
|
|
|
username=user
|
|
|
|
password=pass
|
|
|
|
EOF
|
|
|
|
sleep 2 &&
|
|
|
|
check fill "$HELPER" <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=timeout.tld
|
|
|
|
--
|
2012-06-24 11:40:00 +00:00
|
|
|
protocol=https
|
|
|
|
host=timeout.tld
|
2011-12-10 10:34:14 +00:00
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://timeout.tld'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@timeout.tld'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
}
|
2011-12-10 10:31:11 +00:00
|
|
|
|
2023-06-16 19:55:06 +00:00
|
|
|
helper_test_password_expiry_utc() {
|
|
|
|
HELPER=$1
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) stores password_expiry_utc" '
|
|
|
|
check approve $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry
|
|
|
|
password=pass
|
|
|
|
password_expiry_utc=9999999999
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) gets password_expiry_utc" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry
|
|
|
|
password=pass
|
|
|
|
password_expiry_utc=9999999999
|
|
|
|
--
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) overwrites when password_expiry_utc changes" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
password=pass1
|
|
|
|
password_expiry_utc=9999999998
|
|
|
|
EOF
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
password=pass2
|
|
|
|
password_expiry_utc=9999999999
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
password=pass2
|
|
|
|
password_expiry_utc=9999999999
|
|
|
|
EOF
|
|
|
|
check reject $HELPER <<-\EOF &&
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
password=pass2
|
|
|
|
EOF
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user-expiry-overwrite
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Password for '\''https://user-expiry-overwrite@example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
2023-04-21 09:47:59 +00:00
|
|
|
helper_test_oauth_refresh_token() {
|
|
|
|
HELPER=$1
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) stores oauth_refresh_token" '
|
|
|
|
check approve $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user4
|
|
|
|
password=pass
|
|
|
|
oauth_refresh_token=xyzzy
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) gets oauth_refresh_token" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user4
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=example.com
|
|
|
|
username=user4
|
|
|
|
password=pass
|
|
|
|
oauth_refresh_token=xyzzy
|
|
|
|
--
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
2024-04-17 00:02:38 +00:00
|
|
|
helper_test_authtype() {
|
|
|
|
HELPER=$1
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) stores authtype and credential" '
|
|
|
|
check approve $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
authtype=Bearer
|
|
|
|
credential=random-token
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) gets authtype and credential" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
--
|
|
|
|
capability[]=authtype
|
|
|
|
authtype=Bearer
|
|
|
|
credential=random-token
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
--
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) stores authtype and credential with username" '
|
|
|
|
check approve $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
authtype=Bearer
|
|
|
|
credential=other-token
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
username=foobar
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) gets authtype and credential with username" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
username=foobar
|
|
|
|
--
|
|
|
|
capability[]=authtype
|
|
|
|
authtype=Bearer
|
|
|
|
credential=other-token
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
username=foobar
|
|
|
|
--
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) does not get authtype and credential with different username" '
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
username=barbaz
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=git.example.com
|
|
|
|
username=barbaz
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Password for '\''https://barbaz@git.example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) does not store ephemeral authtype and credential" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
capability[]=authtype
|
|
|
|
authtype=Bearer
|
|
|
|
credential=git2-token
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
ephemeral=1
|
|
|
|
EOF
|
|
|
|
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://git2.example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@git2.example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "helper ($HELPER) does not store ephemeral username and password" '
|
|
|
|
check approve $HELPER <<-\EOF &&
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
user=barbaz
|
|
|
|
password=secret
|
|
|
|
ephemeral=1
|
|
|
|
EOF
|
|
|
|
|
|
|
|
check fill $HELPER <<-\EOF
|
|
|
|
capability[]=authtype
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
--
|
|
|
|
protocol=https
|
|
|
|
host=git2.example.com
|
|
|
|
username=askpass-username
|
|
|
|
password=askpass-password
|
|
|
|
--
|
|
|
|
askpass: Username for '\''https://git2.example.com'\'':
|
|
|
|
askpass: Password for '\''https://askpass-username@git2.example.com'\'':
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
2014-09-29 07:02:07 +00:00
|
|
|
write_script askpass <<\EOF
|
2011-12-10 10:31:11 +00:00
|
|
|
echo >&2 askpass: $*
|
2014-04-23 13:44:03 +00:00
|
|
|
what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
|
2011-12-10 10:31:11 +00:00
|
|
|
echo "askpass-$what"
|
|
|
|
EOF
|
|
|
|
GIT_ASKPASS="$PWD/askpass"
|
|
|
|
export GIT_ASKPASS
|