From fe23b90cd10bcfa6c462c9b76d4c89920cb52293 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Tue, 7 Jul 2020 15:13:11 +0200 Subject: [PATCH] fix: use certificate authentication also in bootstrap-user Change-Id: I517102fea5ed51b49cfdc224fbb803b8a6f4df97 --- bootstrap-user | 87 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/bootstrap-user b/bootstrap-user index f310d76..76935bd 100755 --- a/bootstrap-user +++ b/bootstrap-user @@ -12,6 +12,11 @@ function mcurl { shift curl -s --header "X-Real-Proto: https" --header "Host: www.$hostname" -b $folder/cookie-jar "http://$ip/$url" "$@" } +function mccurl { + local url="$1" + shift + curl -s --header "$(cat ${folder}/certauth.txt)" --header "X-Real-Proto: https" --header "Host: secure.$hostname" -b $folder/cookie-jar "http://$ip/$url" "$@" +} # get the csrf out of a webpage (arguments 1 and 2 can be used to select the correct csrf-token) function csrf { @@ -86,6 +91,30 @@ function check_error { fi } +function issue { + curl=$1 + shift + options=$1 + shift + csrf=$($curl "account/certs/new" | csrf "head -n 1") + + openssl req -newkey rsa:4096 -subj "/CN=blabla" -nodes -out $folder/req -keyout $folder/priv + encoded=$(tr '\n' '?' < $folder/req | sed "s/=/%3D/g;s/+/%2B/g;s/\?/%0A/g") + + $curl account/certs/new -d "CSR=$encoded&process=Next&csrf=$csrf" | check_error + + serial=$($curl account/certs/new "$@" -d "$options&OU=&hash_alg=SHA256&validFrom=now&validity=2y&login=1&description=&process=Issue+Certificate&csrf=$csrf" -v 2>&1 | tee $folder/certlog | grep "< Location: " | sed "s_.*/\([a-f0-9]*\)[^0-9]*_\1_") + echo "Certificate: $serial" + if [[ $serial != "" ]]; then + echo "installing" + $curl "account/certs/$serial.crt?chain&noAnchor" > $folder/cert.crt + $curl "account/certs/$serial.crt" > $folder/onlycert.crt + return 0; + else + return 1; + fi +} + if ! type curl > /dev/null; then echo "requires curl" >&2 exit 1 @@ -133,6 +162,8 @@ INSERT INTO user_groups("user","permission","grantedby") VALUES((SELECT "id" FRO INSERT INTO notary("from","to","points","location","when","date") VALUES((SELECT "id" FROM "users" WHERE "email"='$secondaryEmail'), (SELECT "preferredName" FROM "users" WHERE "email"='$adminEmail'), 100, 'initial', CURRENT_TIMESTAMP, '$(date +%Y-%m-%d)'); INSERT INTO notary("from","to","points","location","when","date") VALUES((SELECT "id" FROM "users" WHERE "email"='$adminEmail'), (SELECT "preferredName" FROM "users" WHERE "email"='$secondaryEmail'), 100, 'initial', CURRENT_TIMESTAMP, '$(date +%Y-%m-%d)'); INSERT INTO cats_passed("user_id", "variant_id") VALUES((SELECT "id" FROM "users" WHERE "email"='$adminEmail'),1); +INSERT INTO cats_passed("user_id", "variant_id") VALUES((SELECT "id" FROM "users" WHERE "email"='$adminEmail'),2); +INSERT INTO cats_passed("user_id", "variant_id") VALUES((SELECT "id" FROM "users" WHERE "email"='$adminEmail'),6); EOF sudo lxc-attach -n gigi -- systemctl stop gigi-proxy.service @@ -141,9 +172,22 @@ open-jar $folder/cookie-jar mcurl login -c $folder/cookie-jar --data-urlencode "username=$adminEmail" --data-urlencode "password=$adminPw" --data-urlencode "csrf=$csrf" | check_error open-jar $folder/cookie-jar +echo "Creating own cert" +if issue mcurl "profile=client&CN=SomeCA+User" --data-urlencode "SANs=email:$adminEmail"; then + printf "Got own cert!\n" + cat ${folder}/cert.crt ${folder}/priv > gigi-key.pem +else + printf "issuance failed\n" >&2 + exit 1 +fi +sed "s/^/\t/;s/^\t-----BEGIN/X-Client-Cert: -----BEGIN/;s/\r//g" < ${folder}/onlycert.crt > ${folder}/certauth.txt + +mccurl login -c $folder/cookie-jar +open-jar $folder/cookie-jar + echo "Creating organisation" -csrf=$(mcurl "orga/new" | csrf) -mgmOid=$(mcurl "orga/new" -v -d "O=SomeCA&L=town&ST=state&C=AT&contact=ce%40email.org&comments=&action=new&csrf=$csrf" 2>&1 | grep "< Location: " | sed "s_.*/\([0-9]*\)[^0-9]*_\1_") +csrf=$(mccurl "orga/new" | csrf) +mgmOid=$(mccurl "orga/new" -v -d "O=SomeCA&L=town&ST=state&C=AT&contact=ce%40email.org&comments=&action=new&csrf=$csrf" 2>&1 | grep "< Location: " | sed "s_.*/\([0-9]*\)[^0-9]*_\1_") if ! grep -q '^[0-9]\+$' <<< $mgmOid; then echo "Got an Organisation ID that is not a number: $mgmOid." >&2 exit 1 @@ -151,26 +195,26 @@ fi printf "Management Organisation id is \"%s\"\n" "$mgmOid" printf "adding org-domain for org %s: %s\n" "$mgmOid" "$hostname" -csrf=$(mcurl orga/$mgmOid | csrf "head -n 4" "tail -n 1") +csrf=$(mccurl orga/$mgmOid | csrf "head -n 4" "tail -n 1") domainName="$hostname" -mcurl orga/$mgmOid -d "domain=$domainName&addDomain=action&csrf=$csrf" | check_error +mccurl orga/$mgmOid -d "domain=$domainName&addDomain=action&csrf=$csrf" | check_error echo "using SQL to add self as orgadmin for organisation" sudo lxc-attach -n postgres-primary -- su -c "psql -d gigi" postgres <&2 exit 1 fi -csrf=$(mcurl "account/domains/$domain" | tee $folder/domain | csrf "tail -n 1") +csrf=$(mccurl "account/domains/$domain" | tee $folder/domain | csrf "tail -n 1") token=$(grep pre $folder/domain | tail -n 1 | sed "s_.*>\([a-zA-Z0-9]*\)<.*_\1_") name=$(grep "content available at" $folder/domain | sed "s_.*/\([a-zA-Z0-9]*\)\\.txt.*_\1_") @@ -186,34 +230,15 @@ setfacl -m user:puppet:r $folder/self-priv cp --preserve=all $folder/self-priv modules/gigi/files/gigi.key sudo lxc-attach -n front-nginx -- puppet agent --test --verbose -mcurl "account/domains/$domain" -d "HTTPType=y&SSLType=y&ssl-type-0=direct&ssl-port-0=443&ssl-type-1=direct&ssl-port-1=&ssl-type-2=direct&ssl-port-2=&ssl-type-3=direct&ssl-port-3=&csrf=$csrf" | check_error +mccurl "account/domains/$domain" -d "HTTPType=y&SSLType=y&ssl-type-0=direct&ssl-port-0=443&ssl-type-1=direct&ssl-port-1=&ssl-type-2=direct&ssl-port-2=&ssl-type-3=direct&ssl-port-3=&csrf=$csrf" | check_error echo "Pings configured... waiting" sleep 5 -mcurl "account/domains/$domain" > $folder/domainStatus +mccurl "account/domains/$domain" > $folder/domainStatus echo "Issuing certificate for web" -function issue { - options=$1 - csrf=$(mcurl "account/certs/new" | csrf "head -n 1") - - openssl req -newkey rsa:4096 -subj "/CN=blabla" -nodes -out $folder/req -keyout $folder/priv - encoded=$(tr '\n' '?' < $folder/req | sed "s/=/%3D/g;s/+/%2B/g;s/\?/%0A/g") - - mcurl account/certs/new -d "CSR=$encoded&process=Next&csrf=$csrf" | check_error - - serial=$(mcurl account/certs/new -d "$options&OU=&hash_alg=SHA256&validFrom=now&validity=2y&login=1&description=&process=Issue+Certificate&csrf=$csrf" -v 2>&1 | tee $folder/certlog | grep "< Location: " | sed "s_.*/\([a-f0-9]*\)[^0-9]*_\1_") - echo "Certificate: $serial" - if [[ $serial != "" ]]; then - echo "installing" - mcurl "account/certs/$serial.crt?chain&noAnchor" > $folder/cert.crt - return 0; - else - return 1; - fi -} -if issue "profile=server-orga&CN=&SANs=dns%3Awww.$domainName%2Cdns%3Astatic.$domainName%2Cdns%3Aapi.$domainName%2Cdns%3Asecure.$domainName"; then +if issue mccurl "profile=server-orga&CN=&SANs=dns%3Awww.$domainName%2Cdns%3Astatic.$domainName%2Cdns%3Aapi.$domainName%2Cdns%3Asecure.$domainName"; then cp $folder/cert.crt modules/gigi/files/gigi.crt setfacl -m user:puppet:r $folder/priv cp --preserve=all $folder/priv modules/gigi/files/gigi.key @@ -223,7 +248,7 @@ else echo "refusing to update" fi -if issue "profile=mail-orga&CN=Gigi+System&SANs=email%3Agigi@$domainName"; then +if issue mccurl "profile=mail-orga&CN=Gigi+System&SANs=email%3Agigi@$domainName"; then echo "great!" keystorepw=$(head -c 15 /dev/urandom | base64) openssl pkcs12 -export -name "mail" -in $folder/cert.crt -inkey $folder/priv -CAfile modules/nre/files/config/ca/root.crt -password file:<(printf '%s' "$keystorepw") | sudo tee modules/gigi/files/keystore.pkcs12 > /dev/null -- 2.39.2