fix: switch to using functions instead of calling OpenSSL directly

Also reduced the number of environment variables which simplifies
the documentation and requirements. The variable names now match
those used by the OCI CLI.

Signed-off-by: Avi Miller <avi.miller@oracle.com>
This commit is contained in:
Avi Miller 2021-06-18 10:16:32 +10:00
parent 6f88c81616
commit 017a10189c
No known key found for this signature in database
GPG Key ID: 66D6066620F03B05

View File

@ -3,15 +3,16 @@
# Acme.sh DNS API plugin for Oracle Cloud Infrastructure # Acme.sh DNS API plugin for Oracle Cloud Infrastructure
# Copyright (c) 2021, Oracle and/or its affiliates # Copyright (c) 2021, Oracle and/or its affiliates
# #
# Required environment variables: # Required OCI CLI environment variables:
# - OCI_TENANCY : OCID of tenancy that contains the target DNS zone # - OCI_CLI_TENANCY : OCID of tenancy that contains the target DNS zone
# - OCI_USER : OCID of user with permission to add/remove records from zones # - OCI_CLI_USER : OCID of user with permission to add/remove records from zones
# - OCI_FINGERPRINT: fingerprint of the public key for the user # - OCI_CLI_REGION : Should point to the tenancy home region
# - OCI_PRIVATE_KEY: Path to private API signing key file in PEM format
# #
# Optional environment variables: # One of the following two variables is required:
# - OCI_KEY_PASSPHRASE: if the private key above s encrypted, the passphrase is required # - OCI_CLI_KEY_FILE: Path to private API signing key file in PEM format; or
# - OCI_REGION: Your home region will probably response the fastest # - OCI_CLI_KEY : The private API signing key in PEM format
#
# NOTE: using an encrypted private key that needs a passphrase is not supported.
# #
dns_oci_add() { dns_oci_add() {
@ -20,11 +21,6 @@ dns_oci_add() {
if _oci_config; then if _oci_config; then
if ! _get_zone "$_fqdn"; then
_err "Error: DNS Zone not found for $_fqdn."
return 1
fi
if [ "$_sub_domain" ] && [ "$_domain" ]; then if [ "$_sub_domain" ] && [ "$_domain" ]; then
_add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}" _add_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"ttl\": 30,\"operation\":\"ADD\"}]}"
response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body") response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_add_record_body")
@ -48,11 +44,6 @@ dns_oci_rm() {
if _oci_config; then if _oci_config; then
if ! _get_zone "$_fqdn"; then
_err "Error: DNS Zone not found for $_fqdn."
return 1
fi
if [ "$_sub_domain" ] && [ "$_domain" ]; then if [ "$_sub_domain" ] && [ "$_domain" ]; then
_remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}" _remove_record_body="{\"items\":[{\"domain\":\"${_sub_domain}.${_domain}\",\"rdata\":\"$_rdata\",\"rtype\":\"TXT\",\"operation\":\"REMOVE\"}]}"
response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body") response=$(_signed_request "PATCH" "/20180115/zones/${_domain}/records" "$_remove_record_body")
@ -73,59 +64,57 @@ dns_oci_rm() {
#################### Private functions below ################################## #################### Private functions below ##################################
_oci_config() { _oci_config() {
OCI_TENANCY="${OCI_TENANCY:-$(_readaccountconf_mutable OCI_TENANCY)}" OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}"
OCI_USER="${OCI_USER:-$(_readaccountconf_mutable OCI_USER)}" OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}"
OCI_FINGERPRINT="${OCI_FINGERPRINT:-$(_readaccountconf_mutable OCI_FINGERPRINT)}" OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}"
OCI_PRIVATE_KEY="${OCI_PRIVATE_KEY:-$(_readaccountconf_mutable OCI_PRIVATE_KEY)}" OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}"
OCI_KEY_PASSPHRASE="${OCI_KEY_PASSPHRASE:-$(_readaccountconf_mutable OCI_KEY_PASSPHRASE)}"
OCI_REGION="${OCI_REGION:-$(_readaccountconf_mutable OCI_REGION)}"
_not_set="" _not_set=""
_ret=0 _ret=0
if [ -f "$OCI_PRIVATE_KEY" ]; then if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
OCI_PRIVATE_KEY="$(openssl enc -a -A <"$OCI_PRIVATE_KEY")" _err "Fatal: you must provide a value for either OCI_CLI_KEY_FILE or OCI_CLI_KEY."
return 1
fi fi
if [ -z "$OCI_TENANCY" ]; then if [ "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
_not_set="OCI_TENANCY " if [ -f "$OCI_CLI_KEY_FILE" ]; then
OCI_CLI_KEY=$(_base64 <"$OCI_CLI_KEY_FILE")
else
_err "Fatal: unable to read $OCI_CLI_KEY_FILE."
return 1
fi
fi fi
if [ -z "$OCI_USER" ]; then if [ -z "$OCI_CLI_TENANCY" ]; then
_not_set="${_not_set}OCI_USER " _not_set="${_not_set}OCI_CLI_TENANCY "
fi fi
if [ -z "$OCI_FINGERPRINT" ]; then if [ -z "$OCI_CLI_USER" ]; then
_not_set="${_not_set}OCI_FINGERPRINT " _not_set="${_not_set}OCI_CLI_USER "
fi fi
if [ -z "$OCI_PRIVATE_KEY" ]; then if [ -z "$OCI_CLI_REGION" ]; then
_not_set="${_not_set}OCI_PRIVATE_KEY" _not_set="${_not_set}OCI_CLI_REGION "
fi fi
if [ "$_not_set" ]; then if [ "$_not_set" ]; then
_err "Fatal: environment variable(s): ${_not_set} not set." _err "Fatal: required environment variable(s): ${_not_set} not set."
_ret=1 _ret=1
else else
_saveaccountconf_mutable OCI_TENANCY "$OCI_TENANCY" _saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY"
_saveaccountconf_mutable OCI_USER "$OCI_USER" _saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER"
_saveaccountconf_mutable OCI_FINGERPRINT "$OCI_FINGERPRINT" _saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
_saveaccountconf_mutable OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY" _saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION"
fi fi
if [ "$OCI_PRIVATE_KEY" ] && [ "$(printf "%s\n" "$OCI_PRIVATE_KEY" | wc -l)" -eq 1 ]; then if ! _contains "PRIVATE KEY" "$OCI_CLI_KEY"; then
OCI_PRIVATE_KEY="$(echo "$OCI_PRIVATE_KEY" | openssl enc -d -a -A)" OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline)
_secure_debug3 OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY"
fi fi
if [ "$OCI_KEY_PASSPHRASE" ]; then if ! _get_zone "$_fqdn"; then
_saveaccountconf_mutable OCI_KEY_PASSPHRASE "$OCI_KEY_PASSPHRASE" _err "Error: DNS Zone not found for $_fqdn."
fi _ret=1
if [ "$OCI_REGION" ]; then
_saveaccountconf_mutable OCI_REGION "$OCI_REGION"
else
OCI_REGION="us-ashburn-1"
fi fi
return $_ret return $_ret
@ -168,6 +157,19 @@ _get_zone() {
} }
#Usage: privatekey
#Output MD5 fingerprint
_fingerprint() {
pkey="$1"
if [ -z "$pkey" ]; then
_usage "Usage: _fingerprint privkey"
return 1
fi
printf "%s" "$pkey" | ${ACME_OPENSSL_BIN:-openssl} rsa -pubout -outform DER 2>/dev/null | ${ACME_OPENSSL_BIN:-openssl} md5 -c | cut -d = -f 2 | tr -d ' '
}
_signed_request() { _signed_request() {
_sig_method="$1" _sig_method="$1"
@ -175,17 +177,13 @@ _signed_request() {
_sig_body="$3" _sig_body="$3"
_return_field="$4" _return_field="$4"
_sig_host="dns.$OCI_REGION.oraclecloud.com" _key_fingerprint=$(_fingerprint "$OCI_CLI_KEY")
_sig_keyId="$OCI_TENANCY/$OCI_USER/$OCI_FINGERPRINT" _sig_host="dns.$OCI_CLI_REGION.oraclecloud.com"
_sig_keyId="$OCI_CLI_TENANCY/$OCI_CLI_USER/$_key_fingerprint"
_sig_alg="rsa-sha256" _sig_alg="rsa-sha256"
_sig_version="1" _sig_version="1"
_sig_now="$(LC_ALL=C \date -u "+%a, %d %h %Y %H:%M:%S GMT")" _sig_now="$(LC_ALL=C \date -u "+%a, %d %h %Y %H:%M:%S GMT")"
if [ "$OCI_KEY_PASSPHRASE" ]; then
export OCI_KEY_PASSPHRASE="$OCI_KEY_PASSPHRASE"
_sig_passinArg="-passin env:OCI_KEY_PASSPHRASE"
fi
_request_method=$(printf %s "$_sig_method" | _lower_case) _request_method=$(printf %s "$_sig_method" | _lower_case)
_curl_method=$(printf %s "$_sig_method" | _upper_case) _curl_method=$(printf %s "$_sig_method" | _upper_case)
@ -198,7 +196,7 @@ _signed_request() {
if [ "$_sig_body" ]; then if [ "$_sig_body" ]; then
_secure_debug3 _sig_body "$_sig_body" _secure_debug3 _sig_body "$_sig_body"
_sig_body_sha256="x-content-sha256: $(printf %s "$_sig_body" | openssl dgst -binary -sha256 | openssl enc -e -base64)" _sig_body_sha256="x-content-sha256: $(printf %s "$_sig_body" | _digest sha256)"
_sig_body_type="content-type: application/json" _sig_body_type="content-type: application/json"
_sig_body_length="content-length: ${#_sig_body}" _sig_body_length="content-length: ${#_sig_body}"
_string_to_sign="$_string_to_sign\n$_sig_body_sha256\n$_sig_body_type\n$_sig_body_length" _string_to_sign="$_string_to_sign\n$_sig_body_sha256\n$_sig_body_type\n$_sig_body_length"
@ -207,10 +205,8 @@ _signed_request() {
_tmp_file=$(_mktemp) _tmp_file=$(_mktemp)
if [ -f "$_tmp_file" ]; then if [ -f "$_tmp_file" ]; then
printf '%s' "$OCI_PRIVATE_KEY" >"$_tmp_file" printf '%s' "$OCI_CLI_KEY" >"$_tmp_file"
# Double quoting the file and passphrase breaks openssl _signature=$(printf '%b' "$_string_to_sign" | _sign "$_tmp_file" sha256 | tr -d '\r\n')
# shellcheck disable=SC2086
_signature=$(printf '%b' "$_string_to_sign" | openssl dgst -sha256 -sign $_tmp_file $_sig_passinArg | openssl enc -e -base64 | tr -d '\r\n')
rm -f "$_tmp_file" rm -f "$_tmp_file"
fi fi