mirror of
https://github.com/git/git
synced 2024-06-30 22:54:27 +00:00
When initializing the transport helper in `transport_get()`, we allocate the name of the helper. We neither end up transferring ownership of the name, nor do we free it. The associated memory thus leaks. Fix this memory leak by freeing the string at the calling side in `transport_get()`. `transport_helper_init()` now creates its own copy of the string and thus can free it as required. An alterantive way to fix this would be to transfer ownership of the string passed into `transport_helper_init()`, which would avoid the call to xstrdup(1). But it does make for a more surprising calling convention as we do not typically transfer ownership of strings like this. Mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
563 lines
15 KiB
Bash
Executable File
563 lines
15 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='test http auth header and credential helper interop'
|
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
|
. ./test-lib.sh
|
|
. "$TEST_DIRECTORY"/lib-httpd.sh
|
|
|
|
enable_cgipassauth
|
|
if ! test_have_prereq CGIPASSAUTH
|
|
then
|
|
skip_all="no CGIPassAuth support"
|
|
test_done
|
|
fi
|
|
start_httpd
|
|
|
|
test_expect_success 'setup_credential_helper' '
|
|
mkdir "$TRASH_DIRECTORY/bin" &&
|
|
PATH=$PATH:"$TRASH_DIRECTORY/bin" &&
|
|
export PATH &&
|
|
|
|
CREDENTIAL_HELPER="$TRASH_DIRECTORY/bin/git-credential-test-helper" &&
|
|
write_script "$CREDENTIAL_HELPER" <<-\EOF
|
|
cmd=$1
|
|
teefile=$cmd-query-temp.cred
|
|
catfile=$cmd-reply.cred
|
|
sed -n -e "/^$/q" -e "p" >>$teefile
|
|
state=$(sed -ne "s/^state\[\]=helper://p" "$teefile")
|
|
if test -z "$state"
|
|
then
|
|
mv "$teefile" "$cmd-query.cred"
|
|
else
|
|
mv "$teefile" "$cmd-query-$state.cred"
|
|
catfile="$cmd-reply-$state.cred"
|
|
fi
|
|
if test "$cmd" = "get"
|
|
then
|
|
cat $catfile
|
|
fi
|
|
EOF
|
|
'
|
|
|
|
set_credential_reply () {
|
|
local suffix="$(test -n "$2" && echo "-$2")"
|
|
cat >"$TRASH_DIRECTORY/$1-reply$suffix.cred"
|
|
}
|
|
|
|
expect_credential_query () {
|
|
local suffix="$(test -n "$2" && echo "-$2")"
|
|
cat >"$TRASH_DIRECTORY/$1-expect$suffix.cred" &&
|
|
test_cmp "$TRASH_DIRECTORY/$1-expect$suffix.cred" \
|
|
"$TRASH_DIRECTORY/$1-query$suffix.cred"
|
|
}
|
|
|
|
per_test_cleanup () {
|
|
rm -f *.cred &&
|
|
rm -f "$HTTPD_ROOT_PATH"/custom-auth.valid \
|
|
"$HTTPD_ROOT_PATH"/custom-auth.challenge
|
|
}
|
|
|
|
test_expect_success 'setup repository' '
|
|
test_commit foo &&
|
|
git init --bare "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
|
git push --mirror "$HTTPD_DOCUMENT_ROOT_PATH/repo.git"
|
|
'
|
|
|
|
test_expect_success 'access using basic auth' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth via authtype' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
capability[]=authtype
|
|
authtype=Basic
|
|
credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
GIT_CURL_VERBOSE=1 git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
capability[]=authtype
|
|
authtype=Basic
|
|
credential=YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth invalid credentials' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=baduser
|
|
password=wrong-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query erase <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=baduser
|
|
password=wrong-passwd
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth with extra challenges' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
|
|
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth mixed-case wwwauth header name' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=www-authenticate: foobar param1="value1" param2="value2"
|
|
id=default response=WWW-AUTHENTICATE: BEARER authorize_uri="id.example.com" p=1 q=0
|
|
id=default response=WwW-aUtHeNtIcAtE: baSiC realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=foobar param1="value1" param2="value2"
|
|
wwwauth[]=BEARER authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=baSiC realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth with wwwauth header continuations' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
# Note that leading and trailing whitespace is important to correctly
|
|
# simulate a continuation/folded header.
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: FooBar param1="value1"
|
|
id=default response= param2="value2"
|
|
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com"
|
|
id=default response= p=1
|
|
id=default response= q=0
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth with wwwauth header empty continuations' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
|
|
|
|
# Note that leading and trailing whitespace is important to correctly
|
|
# simulate a continuation/folded header.
|
|
printf "id=1 status=200\n" >"$CHALLENGE" &&
|
|
printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= \r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= param2=\"value2\"\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response=WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= p=1\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= \r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= q=0\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" &&
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using basic auth with wwwauth header mixed line-endings' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
|
|
# Basic base64(alice:secret-passwd)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Basic YWxpY2U6c2VjcmV0LXBhc3N3ZA==
|
|
EOF
|
|
|
|
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
|
|
|
|
# Note that leading and trailing whitespace is important to correctly
|
|
# simulate a continuation/folded header.
|
|
printf "id=1 status=200\n" >"$CHALLENGE" &&
|
|
printf "id=default response=WWW-Authenticate: FooBar param1=\"value1\"\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response= \r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response=\tparam2=\"value2\"\r\n" >>"$CHALLENGE" &&
|
|
printf "id=default response=WWW-Authenticate: Basic realm=\"example.com\"" >>"$CHALLENGE" &&
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
username=alice
|
|
password=secret-passwd
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using bearer auth' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
capability[]=authtype
|
|
authtype=Bearer
|
|
credential=YS1naXQtdG9rZW4=
|
|
EOF
|
|
|
|
# Basic base64(a-git-token)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Bearer YS1naXQtdG9rZW4=
|
|
EOF
|
|
|
|
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
|
|
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query store <<-EOF
|
|
capability[]=authtype
|
|
authtype=Bearer
|
|
credential=YS1naXQtdG9rZW4=
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using bearer auth with invalid credentials' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
capability[]=authtype
|
|
authtype=Bearer
|
|
credential=incorrect-token
|
|
EOF
|
|
|
|
# Basic base64(a-git-token)
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Bearer YS1naXQtdG9rZW4=
|
|
EOF
|
|
|
|
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=200
|
|
id=default response=WWW-Authenticate: FooBar param1="value1" param2="value2"
|
|
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
|
id=default response=WWW-Authenticate: Basic realm="example.com"
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
test_must_fail git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
|
|
expect_credential_query erase <<-EOF
|
|
capability[]=authtype
|
|
authtype=Bearer
|
|
credential=incorrect-token
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=FooBar param1="value1" param2="value2"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
wwwauth[]=Basic realm="example.com"
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'access using three-legged auth' '
|
|
test_when_finished "per_test_cleanup" &&
|
|
|
|
set_credential_reply get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
authtype=Multistage
|
|
credential=YS1naXQtdG9rZW4=
|
|
state[]=helper:foobar
|
|
continue=1
|
|
EOF
|
|
|
|
set_credential_reply get foobar <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
authtype=Multistage
|
|
credential=YW5vdGhlci10b2tlbg==
|
|
state[]=helper:bazquux
|
|
EOF
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.valid" <<-EOF &&
|
|
id=1 creds=Multistage YS1naXQtdG9rZW4=
|
|
id=2 creds=Multistage YW5vdGhlci10b2tlbg==
|
|
EOF
|
|
|
|
CHALLENGE="$HTTPD_ROOT_PATH/custom-auth.challenge" &&
|
|
|
|
cat >"$HTTPD_ROOT_PATH/custom-auth.challenge" <<-EOF &&
|
|
id=1 status=401 response=WWW-Authenticate: Multistage challenge="456"
|
|
id=1 status=401 response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
|
id=2 status=200
|
|
id=default response=WWW-Authenticate: Multistage challenge="123"
|
|
id=default response=WWW-Authenticate: Bearer authorize_uri="id.example.com" p=1 q=0
|
|
EOF
|
|
|
|
test_config_global credential.helper test-helper &&
|
|
git ls-remote "$HTTPD_URL/custom_auth/repo.git" &&
|
|
|
|
expect_credential_query get <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=Multistage challenge="123"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
EOF
|
|
|
|
expect_credential_query get foobar <<-EOF &&
|
|
capability[]=authtype
|
|
capability[]=state
|
|
authtype=Multistage
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
wwwauth[]=Multistage challenge="456"
|
|
wwwauth[]=Bearer authorize_uri="id.example.com" p=1 q=0
|
|
state[]=helper:foobar
|
|
EOF
|
|
|
|
expect_credential_query store bazquux <<-EOF
|
|
capability[]=authtype
|
|
capability[]=state
|
|
authtype=Multistage
|
|
credential=YW5vdGhlci10b2tlbg==
|
|
protocol=http
|
|
host=$HTTPD_DEST
|
|
state[]=helper:bazquux
|
|
EOF
|
|
'
|
|
|
|
test_done
|