merged temporary json.sh into dehydrated, fixed authorization "pending" loop

This commit is contained in:
Lukas Schauer
2020-07-04 21:51:32 +02:00
parent 7f970b527c
commit bb5a1473d1
3 changed files with 199 additions and 198 deletions

View File

@@ -9,6 +9,7 @@ This file contains a log of major changes in dehydrated
- Don't include keyAuthorization in challenge validation (RFC compliance)
## Changed
- Use JSON.sh to parse JSON
- Use account URL instead of account ID (RFC compliance)
- Dehydrated now has a new home: https://github.com/dehydrated-io/dehydrated

View File

@@ -17,8 +17,6 @@ umask 077 # paranoid umask, we're creating private keys
exec 3>&-
exec 4>&-
. ./json.sh
VERSION="0.6.6"
# Find directory in which this script is stored by traversing all symbolic links
@@ -33,6 +31,197 @@ SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
BASEDIR="${SCRIPTDIR}"
ORIGARGS="$@"
#!/bin/sh
# Generate json.sh path matching string
json_path() {
if [ ! "${1}" = "-p" ]; then
printf '"%s"' "${1}"
else
printf '%s' "${2}"
fi
}
# Get string value from json dictionary
get_json_string_value() {
local filter
filter="$(printf 's/.*\[%s\]\s*"\([^"]*\)"/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}"
}
# Get array values from json dictionary
get_json_array_values() {
grep -E '^\['"$(json_path "${1:-}" "${2:-}")"',[0-9]*\]' | sed -e 's/\[[^\]*\]\s*//g' -e 's/^"//' -e 's/"$//'
}
# Get sub-dictionary from json
get_json_dict_value() {
local filter
echo "$(json_path "${1:-}" "${2:-}")"
filter="$(printf 's/.*\[%s\]\s*\(.*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}" | jsonsh
}
# Get integer value from json
get_json_int_value() {
local filter
filter="$(printf 's/.*\[%s\]\s*\([^"]*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}"
}
# JSON.sh JSON-parser
# Modified from https://github.com/dominictarr/JSON.sh
# Original Copyright (c) 2011 Dominic Tarr
# Licensed under The MIT License
jsonsh() {
throw() {
echo "$*" >&2
exit 1
}
awk_egrep () {
local pattern_string=$1
gawk '{
while ($0) {
start=match($0, pattern);
token=substr($0, start, RLENGTH);
print token;
$0=substr($0, start+RLENGTH);
}
}' pattern="$pattern_string"
}
tokenize () {
local GREP
local ESCAPE
local CHAR
if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
then
GREP='egrep -ao --color=never'
else
GREP='egrep -ao'
fi
if echo "test string" | egrep -o "test" >/dev/null 2>&1
then
ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
CHAR='[^[:cntrl:]"\\]'
else
GREP=awk_egrep
ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
CHAR='[^[:cntrl:]"\\\\]'
fi
local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
local KEYWORD='null|false|true'
local SPACE='[[:space:]]+'
# Force zsh to expand $A into multiple words
local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
$GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
}
parse_array () {
local index=0
local ary=''
read -r token
case "$token" in
']') ;;
*)
while :
do
parse_value "$1" "$index"
index=$((index+1))
ary="$ary""$value"
read -r token
case "$token" in
']') break ;;
',') ary="$ary," ;;
*) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '[%s]' "$ary") || value=
:
}
parse_object () {
local key
local obj=''
read -r token
case "$token" in
'}') ;;
*)
while :
do
case "$token" in
'"'*'"') key=$token ;;
*) throw "EXPECTED string GOT ${token:-EOF}" ;;
esac
read -r token
case "$token" in
':') ;;
*) throw "EXPECTED : GOT ${token:-EOF}" ;;
esac
read -r token
parse_value "$1" "$key"
obj="$obj$key:$value"
read -r token
case "$token" in
'}') break ;;
',') obj="$obj," ;;
*) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '{%s}' "$obj") || value=
:
}
parse_value () {
local jpath="${1:+$1,}${2:-}" isleaf=0 isempty=0 print=0
case "$token" in
'{') parse_object "$jpath" ;;
'[') parse_array "$jpath" ;;
# At this point, the only valid single-character tokens are digits.
''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
*) value=$token
# replace solidus ("\/") in json strings with normalized value: "/"
value=$(echo "$value" | sed 's#\\/#/#g')
isleaf=1
[ "$value" = '""' ] && isempty=1
;;
esac
[ "$value" = '' ] && return
[ -z "$jpath" ] && return # do not print head
printf "[%s]\t%s\n" "$jpath" "$value"
:
}
parse () {
read -r token
parse_value
read -r token
case "$token" in
'') ;;
*) throw "EXPECTED EOF GOT $token" ;;
esac
}
tokenize | parse
}
# Create (identifiable) temporary files
_mktemp() {
# shellcheck disable=SC2068
@@ -300,8 +489,7 @@ init_system() {
fi
# Get CA URLs
CA_DIRECTORY_RAW="$(http_request get "${CA}")"
CA_DIRECTORY="$(printf "%s" "${CA_DIRECTORY_RAW}" | jsonsh)"
CA_DIRECTORY="$(http_request get "${CA}" | jsonsh)"
# Automatic discovery of API version
if [[ "${API}" = "auto" ]]; then
@@ -696,7 +884,7 @@ sign_csr() {
if [[ "${API}" -eq 2 ]]; then
# Receive authorization ($authorization is authz uri)
response="$(signed_request "$(echo "${authorization}" | _sed -e 's/\"(.*)".*/\1/')" "" | jsonsh)"
identifier="$(echo "${response}" | get_json_dict_value identifier | get_json_string_value value)"
identifier="$(echo "${response}" | get_json_string_value -p '"identifier","value"')"
echo " + Handling authorization for ${identifier}"
else
# Request new authorization ($authorization is altname)
@@ -790,9 +978,9 @@ sign_csr() {
while [[ "${reqstatus}" = "pending" ]]; do
sleep 1
if [[ "${API}" -eq 2 ]]; then
result="$(signed_request "${challenge_uris[${idx}]}" "")"
result="$(signed_request "${challenge_uris[${idx}]}" "" | jsonsh)"
else
result="$(http_request get "${challenge_uris[${idx}]}")"
result="$(http_request get "${challenge_uris[${idx}]}" | jsonsh)"
fi
reqstatus="$(echo "${result}" | get_json_string_value status)"
done
@@ -856,7 +1044,7 @@ sign_csr() {
_exiterr "Order in status ${status}"
;;
esac
result="$(signed_request "${order_location}" "" | clean_json)"
result="$(signed_request "${order_location}" "" | jsonsh)"
done
certificate="$(echo "${result}" | get_json_string_value certificate)"
crt="$(signed_request "${certificate}" "")"
@@ -1798,3 +1986,5 @@ if [[ ! "${DEHYDRATED_NOOP:-}" = "NOOP" ]]; then
# Run script
main "${@:-}"
fi
# vi: expandtab sw=2 ts=2

190
json.sh
View File

@@ -1,190 +0,0 @@
#!/bin/sh
# Generate json.sh path matching string
json_path() {
if [ ! "${1}" = "-p" ]; then
printf '"%s"' "${1}"
else
printf '%s' "${2}"
fi
}
# Get string value from json dictionary
get_json_string_value() {
local filter
filter="$(printf 's/.*\[%s\]\s*"\([^"]*\)"/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}"
}
# Get array values from json dictionary
get_json_array_values() {
grep -E '^\["'"$1"'",[0-9]*\]' | sed -e 's/\[[^\]*\]\s*//g' -e 's/^"//' -e 's/"$//'
}
# Get sub-dictionary from json
get_json_dict_value() {
local filter
echo "$(json_path "${1:-}" "${2:-}")"
filter="$(printf 's/.*\[%s\]\s*\(.*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}" | jsonsh
}
# Get integer value from json
get_json_int_value() {
local filter
filter="$(printf 's/.*\[%s\]\s*\([^"]*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
sed -n "${filter}"
}
jsonsh() {
# Modified from https://github.com/dominictarr/JSON.sh
# Original Copyright (c) 2011 Dominic Tarr
# Licensed under The MIT License
throw() {
echo "$*" >&2
exit 1
}
awk_egrep () {
local pattern_string=$1
gawk '{
while ($0) {
start=match($0, pattern);
token=substr($0, start, RLENGTH);
print token;
$0=substr($0, start+RLENGTH);
}
}' pattern="$pattern_string"
}
tokenize () {
local GREP
local ESCAPE
local CHAR
if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
then
GREP='egrep -ao --color=never'
else
GREP='egrep -ao'
fi
if echo "test string" | egrep -o "test" >/dev/null 2>&1
then
ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
CHAR='[^[:cntrl:]"\\]'
else
GREP=awk_egrep
ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
CHAR='[^[:cntrl:]"\\\\]'
fi
local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
local KEYWORD='null|false|true'
local SPACE='[[:space:]]+'
# Force zsh to expand $A into multiple words
local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
$GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
}
parse_array () {
local index=0
local ary=''
read -r token
case "$token" in
']') ;;
*)
while :
do
parse_value "$1" "$index"
index=$((index+1))
ary="$ary""$value"
read -r token
case "$token" in
']') break ;;
',') ary="$ary," ;;
*) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '[%s]' "$ary") || value=
:
}
parse_object () {
local key
local obj=''
read -r token
case "$token" in
'}') ;;
*)
while :
do
case "$token" in
'"'*'"') key=$token ;;
*) throw "EXPECTED string GOT ${token:-EOF}" ;;
esac
read -r token
case "$token" in
':') ;;
*) throw "EXPECTED : GOT ${token:-EOF}" ;;
esac
read -r token
parse_value "$1" "$key"
obj="$obj$key:$value"
read -r token
case "$token" in
'}') break ;;
',') obj="$obj," ;;
*) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '{%s}' "$obj") || value=
:
}
parse_value () {
local jpath="${1:+$1,}${2:-}" isleaf=0 isempty=0 print=0
case "$token" in
'{') parse_object "$jpath" ;;
'[') parse_array "$jpath" ;;
# At this point, the only valid single-character tokens are digits.
''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
*) value=$token
# replace solidus ("\/") in json strings with normalized value: "/"
value=$(echo "$value" | sed 's#\\/#/#g')
isleaf=1
[ "$value" = '""' ] && isempty=1
;;
esac
[ "$value" = '' ] && return
[ -z "$jpath" ] && return # do not print head
printf "[%s]\t%s\n" "$jpath" "$value"
:
}
parse () {
read -r token
parse_value
read -r token
case "$token" in
'') ;;
*) throw "EXPECTED EOF GOT $token" ;;
esac
}
tokenize | parse
}
# vi: expandtab sw=2 ts=2