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
1 changed files with 58 additions and 62 deletions

View File

@ -3,15 +3,16 @@
# Acme.sh DNS API plugin for Oracle Cloud Infrastructure
# Copyright (c) 2021, Oracle and/or its affiliates
#
# Required environment variables:
# - OCI_TENANCY : OCID of tenancy that contains the target DNS zone
# - OCI_USER : OCID of user with permission to add/remove records from zones
# - OCI_FINGERPRINT: fingerprint of the public key for the user
# - OCI_PRIVATE_KEY: Path to private API signing key file in PEM format
# Required OCI CLI environment variables:
# - OCI_CLI_TENANCY : OCID of tenancy that contains the target DNS zone
# - OCI_CLI_USER : OCID of user with permission to add/remove records from zones
# - OCI_CLI_REGION : Should point to the tenancy home region
#
# Optional environment variables:
# - OCI_KEY_PASSPHRASE: if the private key above s encrypted, the passphrase is required
# - OCI_REGION: Your home region will probably response the fastest
# One of the following two variables is required:
# - OCI_CLI_KEY_FILE: Path to private API signing key file in PEM format; or
# - 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() {
@ -20,11 +21,6 @@ dns_oci_add() {
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
_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")
@ -48,11 +44,6 @@ dns_oci_rm() {
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
_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")
@ -73,59 +64,57 @@ dns_oci_rm() {
#################### Private functions below ##################################
_oci_config() {
OCI_TENANCY="${OCI_TENANCY:-$(_readaccountconf_mutable OCI_TENANCY)}"
OCI_USER="${OCI_USER:-$(_readaccountconf_mutable OCI_USER)}"
OCI_FINGERPRINT="${OCI_FINGERPRINT:-$(_readaccountconf_mutable OCI_FINGERPRINT)}"
OCI_PRIVATE_KEY="${OCI_PRIVATE_KEY:-$(_readaccountconf_mutable OCI_PRIVATE_KEY)}"
OCI_KEY_PASSPHRASE="${OCI_KEY_PASSPHRASE:-$(_readaccountconf_mutable OCI_KEY_PASSPHRASE)}"
OCI_REGION="${OCI_REGION:-$(_readaccountconf_mutable OCI_REGION)}"
OCI_CLI_TENANCY="${OCI_CLI_TENANCY:-$(_readaccountconf_mutable OCI_CLI_TENANCY)}"
OCI_CLI_USER="${OCI_CLI_USER:-$(_readaccountconf_mutable OCI_CLI_USER)}"
OCI_CLI_KEY="${OCI_CLI_KEY:-$(_readaccountconf_mutable OCI_CLI_KEY)}"
OCI_CLI_REGION="${OCI_CLI_REGION:-$(_readaccountconf_mutable OCI_CLI_REGION)}"
_not_set=""
_ret=0
if [ -f "$OCI_PRIVATE_KEY" ]; then
OCI_PRIVATE_KEY="$(openssl enc -a -A <"$OCI_PRIVATE_KEY")"
if [ -z "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
_err "Fatal: you must provide a value for either OCI_CLI_KEY_FILE or OCI_CLI_KEY."
return 1
fi
if [ -z "$OCI_TENANCY" ]; then
_not_set="OCI_TENANCY "
if [ "$OCI_CLI_KEY_FILE" ] && [ -z "$OCI_CLI_KEY" ]; then
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
if [ -z "$OCI_USER" ]; then
_not_set="${_not_set}OCI_USER "
if [ -z "$OCI_CLI_TENANCY" ]; then
_not_set="${_not_set}OCI_CLI_TENANCY "
fi
if [ -z "$OCI_FINGERPRINT" ]; then
_not_set="${_not_set}OCI_FINGERPRINT "
if [ -z "$OCI_CLI_USER" ]; then
_not_set="${_not_set}OCI_CLI_USER "
fi
if [ -z "$OCI_PRIVATE_KEY" ]; then
_not_set="${_not_set}OCI_PRIVATE_KEY"
if [ -z "$OCI_CLI_REGION" ]; then
_not_set="${_not_set}OCI_CLI_REGION "
fi
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
else
_saveaccountconf_mutable OCI_TENANCY "$OCI_TENANCY"
_saveaccountconf_mutable OCI_USER "$OCI_USER"
_saveaccountconf_mutable OCI_FINGERPRINT "$OCI_FINGERPRINT"
_saveaccountconf_mutable OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY"
_saveaccountconf_mutable OCI_CLI_TENANCY "$OCI_CLI_TENANCY"
_saveaccountconf_mutable OCI_CLI_USER "$OCI_CLI_USER"
_saveaccountconf_mutable OCI_CLI_KEY "$OCI_CLI_KEY"
_saveaccountconf_mutable OCI_CLI_REGION "$OCI_CLI_REGION"
fi
if [ "$OCI_PRIVATE_KEY" ] && [ "$(printf "%s\n" "$OCI_PRIVATE_KEY" | wc -l)" -eq 1 ]; then
OCI_PRIVATE_KEY="$(echo "$OCI_PRIVATE_KEY" | openssl enc -d -a -A)"
_secure_debug3 OCI_PRIVATE_KEY "$OCI_PRIVATE_KEY"
if ! _contains "PRIVATE KEY" "$OCI_CLI_KEY"; then
OCI_CLI_KEY=$(printf "%s" "$OCI_CLI_KEY" | _dbase64 multiline)
fi
if [ "$OCI_KEY_PASSPHRASE" ]; then
_saveaccountconf_mutable OCI_KEY_PASSPHRASE "$OCI_KEY_PASSPHRASE"
fi
if [ "$OCI_REGION" ]; then
_saveaccountconf_mutable OCI_REGION "$OCI_REGION"
else
OCI_REGION="us-ashburn-1"
if ! _get_zone "$_fqdn"; then
_err "Error: DNS Zone not found for $_fqdn."
_ret=1
fi
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() {
_sig_method="$1"
@ -175,17 +177,13 @@ _signed_request() {
_sig_body="$3"
_return_field="$4"
_sig_host="dns.$OCI_REGION.oraclecloud.com"
_sig_keyId="$OCI_TENANCY/$OCI_USER/$OCI_FINGERPRINT"
_key_fingerprint=$(_fingerprint "$OCI_CLI_KEY")
_sig_host="dns.$OCI_CLI_REGION.oraclecloud.com"
_sig_keyId="$OCI_CLI_TENANCY/$OCI_CLI_USER/$_key_fingerprint"
_sig_alg="rsa-sha256"
_sig_version="1"
_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)
_curl_method=$(printf %s "$_sig_method" | _upper_case)
@ -198,7 +196,7 @@ _signed_request() {
if [ "$_sig_body" ]; then
_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_length="content-length: ${#_sig_body}"
_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)
if [ -f "$_tmp_file" ]; then
printf '%s' "$OCI_PRIVATE_KEY" >"$_tmp_file"
# Double quoting the file and passphrase breaks openssl
# 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')
printf '%s' "$OCI_CLI_KEY" >"$_tmp_file"
_signature=$(printf '%b' "$_string_to_sign" | _sign "$_tmp_file" sha256 | tr -d '\r\n')
rm -f "$_tmp_file"
fi