cmd/certificates: auth export improvements & certificates test script (#2897)

This commit is contained in:
Bryan White 2019-09-04 19:58:38 +02:00 committed by Stefan Benten
parent af5fb8e9c5
commit 62df8ddb0c
7 changed files with 171 additions and 110 deletions

View File

@ -89,6 +89,7 @@ pipeline {
steps {
sh 'psql -U postgres -c \'create database teststorj2;\''
sh 'make test-sim'
sh 'make test-certificates'
}
}

View File

@ -97,10 +97,10 @@ test-sim: ## Test source with storj-sim (jenkins)
@echo "Running ${@}"
@./scripts/test-sim.sh
.PHONY: test-certificate-signing
test-certificate-signing: ## Test certificate signing service and storagenode setup (jenkins)
.PHONY: test-certificates
test-certificates: ## Test certificate signing service and storagenode setup (jenkins)
@echo "Running ${@}"
@./scripts/test-certificate-signing.sh
@./scripts/test-certificates.sh
.PHONY: test-docker
test-docker: ## Run tests in Docker

View File

@ -257,7 +257,12 @@ func writeAuthExport(ctx context.Context, authDB *certificates.AuthorizationDB,
var authErrs errs.Group
for _, auth := range auths {
if err := w.Write([]string{email, auth.Token.String()}); err != nil {
isClaimed := "false"
if auth.Claim != nil {
isClaimed = "true"
}
if err := w.Write([]string{email, auth.Token.String(), isClaimed}); err != nil {
authErrs.Add(err)
}
}

View File

@ -77,8 +77,7 @@ func main() {
defaultConfDir := fpath.ApplicationDir("storj", "cert-signing")
defaultIdentityDir := fpath.ApplicationDir("storj", "identity", "certificates")
cfgstruct.SetupFlag(zap.L(), rootCmd, &confDir, "config-dir", defaultConfDir, "main directory for certificates configuration")
//cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", fpath.ApplicationDir("storj", "identity", "bootstrap"), "main directory for bootstrap identity credentials")
rootCmd.PersistentFlags().StringVar(&identityDir, "identity-dir", defaultIdentityDir, "main directory for storagenode identity credentials")
cfgstruct.SetupFlag(zap.L(), rootCmd, &identityDir, "identity-dir", defaultIdentityDir, "main directory for bootstrap identity credentials")
defaults := cfgstruct.DefaultsFlag(rootCmd)
rootCmd.AddCommand(authCmd)

View File

@ -1,104 +0,0 @@
#!/usr/bin/env bash
set -o errexit
trap "echo ERROR: exiting due to error; exit" ERR
trap "exit" INT TERM
. $(dirname $0)/utils.sh
failures=3
user_id="user@mail.test"
signer_address="127.0.0.1:8888"
difficulty=16
cleanup() {
if [[ ! -z ${bg+x} ]]; then
kill ${bg}
fi
dirs="$tmp $tmp_build_dir"
for dir in ${dirs}; do
if [[ ! -z ${dir+x} ]]; then
rm -rf ${dir}
fi
done
}
if [[ ${TRAVIS} == true ]]; then
declare_cmds storagenode certificates
else
temp_build storagenode certificates
fi
tmp=$(mktemp -d)
trap "cleanup" EXIT
certificates_dir=${tmp}/cert-signing
storagenode_dir=${tmp}/storagenode
# TODO: create separate signer CA and use `--signer.ca` options
# --signer.ca.cert-path ${signer_cert} \
# --signer.ca.key-path ${signer_key} \
echo "setting up certificate signing server"
$certificates setup --config-dir ${certificates_dir} \
--signer.min-difficulty ${difficulty}
echo "creating test authorization"
$certificates auth create --config-dir ${certificates_dir} \
1 ${user_id} >/dev/null 2>&1
export_tokens() {
$certificates auth export --config-dir ${certificates_dir} \
--out -
}
token=$(export_tokens 2>&1|cut -d , -f 2|grep -oE "$user_id:\w+")
echo "starting certificate signing server"
$certificates run --config-dir ${certificates_dir} \
--server.address ${signer_address} >/dev/null 2>&1 &
bg=$!
sleep 1
echo "setting up storage node"
$storagenode setup --config-dir ${storagenode_dir} \
--ca.difficulty ${difficulty} \
--signer.address ${signer_address} \
--signer.auth-token ${token}
ca_chain_len=$(cat ${storagenode_dir}/ca.cert|grep "BEGIN CERTIFICATE"|wc -l)
ident_chain_len=$(cat ${storagenode_dir}/identity.cert|grep "BEGIN CERTIFICATE"|wc -l)
echo "Checks (${failures}):"
if [[ ${ca_chain_len} == 2 ]]; then
echo " - ca chain length is correct"
failures=$((failures-1))
else
echo " - FAIL: incorrect storage node CA chain length; expected: 2; actual: ${ca_chain_len}"
fi
if [[ ${ident_chain_len} == 3 ]]; then
echo " - identity chain length is correct"
failures=$((failures-1))
else
echo " - FAIL: incorrect storage node identity chain length; expected: 2; actual: ${ident_chain_len}"
fi
verify=$(${certificates} verify --config-dir ${certificates_dir} --log.level error 2>&1)
if [[ ! -n ${verify} ]]; then
echo " - certificates verified"
failures=$((failures-1))
else
echo " - FAIL: certificate verification error"
echo " ${verify}"
fi
if [[ ${failures} == 0 ]]; then
echo "SUCCESS: all expectations met!"
else
echo "FAILURE: ${failures} checks failed"
fi
exit ${failures}

124
scripts/test-certificates.sh Executable file
View File

@ -0,0 +1,124 @@
#!/usr/bin/env bash
set -ueo pipefail
source $(dirname $0)/utils.sh
TMPDIR=$(mktemp -d -t tmp.XXXXXXXXXX)
IDENTS_DIR=$TMPDIR/identities
CERTS_DIR=$TMPDIR/certificates
CERTS_ADDR=127.0.0.4:11000
CERTS_ADDR_PRIV=127.0.0.4:11001
kill_certificates_server() {
kill $CERTS_PID
}
cleanup() {
if [[ -n $(ps | grep "certificates") ]]; then
kill_certificates_server
fi
rm -rf "$TMPDIR"
echo "cleaned up test successfully"
}
trap cleanup EXIT INT
_certificates() {
subcommand=$1
shift
ident_dir="${IDENTS_DIR}/certificates"
ca_cert_path="${ident_dir}/ca.cert"
ca_key_path="${ident_dir}/ca.key"
rev_dburl="bolt://${CERTS_DIR}/revocations.db"
# NB: `--identity-dir` and `--config-dir` flags are only bound globally to subcommands
exec certificates --identity-dir "$ident_dir" \
--config-dir "$CERTS_DIR" \
"$subcommand" \
--signer.ca.cert-path "$ca_cert_path" \
--signer.ca.key-path "$ca_key_path" \
--server.address "$CERTS_ADDR" \
--server.private-address "$CERTS_ADDR_PRIV" \
--server.revocation-dburl="$rev_dburl" \
--log.level warn \
"$@"
}
_identity() {
subcommand=$1
rev_dburl="bolt://${IDENTS_DIR}/revocations.db"
shift
# NB: `--identity-dir` and `--config-dir` flags are only bound globally to subcommands
identity --identity-dir "$IDENTS_DIR" \
"$subcommand" \
--signer.tls.revocation-dburl "$rev_dburl" \
--log.level info \
"$@"
}
_identity_create() {
_identity create $1 --difficulty 0 --concurrency 1 >/dev/null
}
_identity_create 'certificates'
_certificates setup &
wait
for i in {0..4}; do
email="testuser${i}@mail.example"
ident_name="testidentity${i}"
_identity_create $ident_name
if [[ i -gt 0 ]]; then
_certificates auth create "$i" "$email" &
wait
fi
done
exported_auths=$(_certificates auth export)
_certificates run --signer.min-difficulty 0 &
CERTS_PID=$!
sleep 1
for i in {1..4}; do
email="testuser${i}@mail.example"
ident_name="testidentity${i}"
token=$(echo "$exported_auths" | grep "$email" | head -n 1 | awk -F , '{print $2}')
_identity authorize --signer.address "$CERTS_ADDR" "$ident_name" "$token" > /dev/null
done
# NB: Certificates server uses bolt by default so it must be shut down before we can export.
kill_certificates_server
# Expect 10 authorizations total.
auths=$(_certificates auth export)
require_lines 10 "$auths" $LINENO
for i in {1..4}; do
email="testuser${i}@mail.example"
claimed_auth_count=0
# Expect number of auths for a given user to equal the identity/email number.
# (e.g. testidentity3/testuser3@mail.example should have 3 auths)
match_auths=$(echo "$auths" | grep "$email" )
require_lines $i "$match_auths" $LINENO
for auth in $match_auths; do
claimed=$(echo "$auth" | awk -F , '{print $3}')
if [[ $claimed == "true" ]]; then
((++claimed_auth_count))
continue
fi
# Expect unclaimed auths to have "false" as the third field.
require_equal "false" "$claimed" $LINENO
done
# Expect 4 auths (one for each user) to be claimed.
require_equal "1" "$claimed_auth_count" $LINENO
done
echo "TEST COMPLETED SUCCESSFULLY!"

View File

@ -1,5 +1,41 @@
#!/usr/bin/env bash
new_error() {
file=$0
err_msg=$1
line_no=$2
echo -e "ERROR: ${file}: line ${line_no}: ${err_msg}"
exit 1
}
require_empty() {
line_no=$2
if [[ -z $(sed -e 's/^[[:space:]]*//') ]]; then
new_error "expected \"$1\" to be an empty string" $line_no
fi
}
require_equal() {
a=$1
b=$2
line_no=$3
if [[ "$a" != "$b" ]]; then
new_error "expected equal:\n$(diff <(echo $a) <(echo $b))" $line_no
fi
}
require_lines() {
line_no=$3
string=$2
line_count=$(echo "$string" | wc -l)
if [[ "$line_count" -lt "$1" ]]; then
new_error "expected number of lines ${line_count} to be ${1}:\n$2" $line_no
fi
}
dots() {
echo -n "."
sleep 1