Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
130e8dbd
Unverified
Commit
130e8dbd
authored
May 23, 2021
by
neil
Committed by
GitHub
May 23, 2021
Browse files
Merge pull request #3522 from acmesh-official/dev
sync
parents
7f2699c6
40e2ebed
Changes
5
Show whitespace changes
Inline
Side-by-side
.github/workflows/LetsEncrypt.yml
View file @
130e8dbd
...
@@ -15,30 +15,9 @@ on:
...
@@ -15,30 +15,9 @@ on:
jobs
:
jobs
:
CheckToken
:
runs-on
:
ubuntu-latest
outputs
:
hasToken
:
${{ steps.step_one.outputs.hasToken }}
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
steps
:
-
name
:
Set the value
id
:
step_one
run
:
|
if [ "$NGROK_TOKEN" ] ; then
echo "::set-output name=hasToken::true"
else
echo "::set-output name=hasToken::false"
fi
-
name
:
Check the value
run
:
echo ${{ steps.step_one.outputs.hasToken }}
Ubuntu
:
Ubuntu
:
runs-on
:
ubuntu-latest
runs-on
:
ubuntu-latest
needs
:
CheckToken
if
:
"
contains(needs.CheckToken.outputs.hasToken,
'true')"
env
:
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
TEST_LOCAL
:
1
TEST_LOCAL
:
1
steps
:
steps
:
-
uses
:
actions/checkout@v2
-
uses
:
actions/checkout@v2
...
@@ -51,9 +30,7 @@ jobs:
...
@@ -51,9 +30,7 @@ jobs:
MacOS
:
MacOS
:
runs-on
:
macos-latest
runs-on
:
macos-latest
needs
:
Ubuntu
env
:
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
TEST_LOCAL
:
1
TEST_LOCAL
:
1
steps
:
steps
:
-
uses
:
actions/checkout@v2
-
uses
:
actions/checkout@v2
...
@@ -66,11 +43,9 @@ jobs:
...
@@ -66,11 +43,9 @@ jobs:
Windows
:
Windows
:
runs-on
:
windows-latest
runs-on
:
windows-latest
needs
:
MacOS
env
:
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
TEST_LOCAL
:
1
TEST_LOCAL
:
1
#The 80 port is used by Windows server, we have to use a custom port,
ngrok
will also use this port.
#The 80 port is used by Windows server, we have to use a custom port,
tunnel
will also use this port.
Le_HTTPPort
:
8888
Le_HTTPPort
:
8888
steps
:
steps
:
-
name
:
Set git to use LF
-
name
:
Set git to use LF
...
@@ -103,17 +78,24 @@ jobs:
...
@@ -103,17 +78,24 @@ jobs:
FreeBSD
:
FreeBSD
:
runs-on
:
macos-latest
runs-on
:
macos-latest
needs
:
Windows
env
:
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
TEST_LOCAL
:
1
TEST_LOCAL
:
1
steps
:
steps
:
-
uses
:
actions/checkout@v2
-
uses
:
actions/checkout@v2
-
uses
:
vmactions/cf-tunnel@v0.0.1
id
:
tunnel
with
:
protocol
:
http
port
:
8080
-
name
:
Set envs
run
:
echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
-
name
:
Clone acmetest
-
name
:
Clone acmetest
run
:
cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
run
:
cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
-
uses
:
vmactions/freebsd-vm@v0.1.4
-
uses
:
vmactions/freebsd-vm@v0.1.4
with
:
with
:
envs
:
'
NGROK_TOKEN
TEST_LOCAL'
envs
:
'
TEST_LOCAL
TestingDomain'
nat
:
|
"8080": "80"
prepare
:
pkg install -y socat curl
prepare
:
pkg install -y socat curl
usesh
:
true
usesh
:
true
run
:
|
run
:
|
...
@@ -121,19 +103,17 @@ jobs:
...
@@ -121,19 +103,17 @@ jobs:
Solaris
:
Solaris
:
runs-on
:
macos-latest
runs-on
:
macos-latest
needs
:
FreeBSD
env
:
env
:
NGROK_TOKEN
:
${{ secrets.NGROK_TOKEN }}
TEST_LOCAL
:
1
TEST_LOCAL
:
1
steps
:
steps
:
-
uses
:
actions/checkout@v2
-
uses
:
actions/checkout@v2
-
uses
:
vmactions/
ngrok
-tunnel@v0.0.1
-
uses
:
vmactions/
cf
-tunnel@v0.0.1
id
:
ngrok
id
:
tunnel
with
:
with
:
protocol
:
http
protocol
:
http
port
:
8080
port
:
8080
-
name
:
Set envs
-
name
:
Set envs
run
:
echo "TestingDomain=${{steps.
ngrok
.outputs.server}}" >> $GITHUB_ENV
run
:
echo "TestingDomain=${{steps.
tunnel
.outputs.server}}" >> $GITHUB_ENV
-
name
:
Clone acmetest
-
name
:
Clone acmetest
run
:
cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
run
:
cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
-
uses
:
vmactions/solaris-vm@v0.0.3
-
uses
:
vmactions/solaris-vm@v0.0.3
...
...
acme.sh
View file @
130e8dbd
...
@@ -20,9 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy"
...
@@ -20,9 +20,6 @@ _SUB_FOLDER_DEPLOY="deploy"
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
LETSENCRYPT_CA_V1
=
"https://acme-v01.api.letsencrypt.org/directory"
LETSENCRYPT_STAGING_CA_V1
=
"https://acme-staging.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
...
@@ -2072,7 +2069,7 @@ _send_signed_request() {
...
@@ -2072,7 +2069,7 @@ _send_signed_request() {
_sleep 2
_sleep 2
continue
continue
fi
fi
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then
if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then
elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then
...
@@ -2080,9 +2077,7 @@ _send_signed_request() {
...
@@ -2080,9 +2077,7 @@ _send_signed_request() {
else
else
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}'
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}'
fi
fi
else
protected
=
"
$JWK_HEADERPLACE_PART1$nonce
\"
,
\"
url
\"
:
\"
${
url
}
$JWK_HEADERPLACE_PART2
,
\"
jwk
\"
:
$jwk
"
'}'
fi
_debug3 protected "$protected"
_debug3 protected "$protected"
protected64="$(printf "%s" "$protected" | _base64 | _url_replace)"
protected64="$(printf "%s" "$protected" | _base64 | _url_replace)"
...
@@ -2549,61 +2544,25 @@ _initAPI() {
...
@@ -2549,61 +2544,25 @@ _initAPI() {
response=$(echo "$response" | _json_decode)
response=$(echo "$response" | _json_decode)
_debug2 "response" "$response"
_debug2 "response" "$response"
ACME_KEY_CHANGE
=
$(
echo
"
$response
"
| _egrep_o
'key-change" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
if
[
-z
"
$ACME_KEY_CHANGE
"
]
;
then
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_KEY_CHANGE
export ACME_KEY_CHANGE
ACME_NEW_AUTHZ
=
$(
echo
"
$response
"
| _egrep_o
'new-authz" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
if
[
-z
"
$ACME_NEW_AUTHZ
"
]
;
then
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_NEW_AUTHZ
export ACME_NEW_AUTHZ
ACME_NEW_ORDER
=
$(
echo
"
$response
"
| _egrep_o
'new-cert" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
ACME_NEW_ORDER_RES
=
"new-cert"
if
[
-z
"
$ACME_NEW_ORDER
"
]
;
then
ACME_NEW_ORDER
=
$(
echo
"
$response
"
| _egrep_o
'new-order" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
ACME_NEW_ORDER_RES
=
"new-order"
if
[
-z
"
$ACME_NEW_ORDER
"
]
;
then
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3)
fi
fi
export ACME_NEW_ORDER
export ACME_NEW_ORDER
export
ACME_NEW_ORDER_RES
ACME_NEW_ACCOUNT
=
$(
echo
"
$response
"
| _egrep_o
'new-reg" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
ACME_NEW_ACCOUNT_RES
=
"new-reg"
if
[
-z
"
$ACME_NEW_ACCOUNT
"
]
;
then
ACME_NEW_ACCOUNT
=
$(
echo
"
$response
"
| _egrep_o
'new-account" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
ACME_NEW_ACCOUNT_RES
=
"new-account"
if
[
-z
"
$ACME_NEW_ACCOUNT
"
]
;
then
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3)
if
[
"
$ACME_NEW_ACCOUNT
"
]
;
then
export
ACME_VERSION
=
2
fi
fi
fi
export ACME_NEW_ACCOUNT
export ACME_NEW_ACCOUNT
export
ACME_NEW_ACCOUNT_RES
ACME_REVOKE_CERT
=
$(
echo
"
$response
"
| _egrep_o
'revoke-cert" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
if
[
-z
"
$ACME_REVOKE_CERT
"
]
;
then
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_REVOKE_CERT
export ACME_REVOKE_CERT
ACME_NEW_NONCE
=
$(
echo
"
$response
"
| _egrep_o
'new-nonce" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
if
[
-z
"
$ACME_NEW_NONCE
"
]
;
then
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_NEW_NONCE
export ACME_NEW_NONCE
ACME_AGREEMENT
=
$(
echo
"
$response
"
| _egrep_o
'terms-of-service" *: *"[^"]*"'
|
cut
-d
'"'
-f
3
)
if
[
-z
"
$ACME_AGREEMENT
"
]
;
then
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_AGREEMENT
export ACME_AGREEMENT
_debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE"
_debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE"
...
@@ -2613,7 +2572,6 @@ _initAPI() {
...
@@ -2613,7 +2572,6 @@ _initAPI() {
_debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT"
_debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT"
_debug "ACME_AGREEMENT" "$ACME_AGREEMENT"
_debug "ACME_AGREEMENT" "$ACME_AGREEMENT"
_debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE"
_debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE"
_debug
"ACME_VERSION"
"
$ACME_VERSION
"
fi
fi
}
}
...
@@ -3563,7 +3521,7 @@ _regAccount() {
...
@@ -3563,7 +3521,7 @@ _regAccount() {
if [ "$_email" ]; then
if [ "$_email" ]; then
_savecaconf "CA_EMAIL" "$_email"
_savecaconf "CA_EMAIL" "$_email"
fi
fi
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then
if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then
if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then
if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then
_info "No EAB credentials found for ZeroSSL, let's get one"
_info "No EAB credentials found for ZeroSSL, let's get one"
...
@@ -3619,13 +3577,6 @@ _regAccount() {
...
@@ -3619,13 +3577,6 @@ _regAccount() {
email_sg="\"contact\": [\"mailto:$_email\"], "
email_sg="\"contact\": [\"mailto:$_email\"], "
fi
fi
regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}"
regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}"
else
_reg_res
=
"
$ACME_NEW_ACCOUNT_RES
"
regjson
=
'{"resource": "'
$_reg_res
'", "terms-of-service-agreed": true, "agreement": "'
$ACME_AGREEMENT
'"}'
if
[
"
$_email
"
]
;
then
regjson
=
'{"resource": "'
$_reg_res
'", "contact": ["mailto:'
$_email
'"], "terms-of-service-agreed": true, "agreement": "'
$ACME_AGREEMENT
'"}'
fi
fi
_info "Registering account: $ACME_DIRECTORY"
_info "Registering account: $ACME_DIRECTORY"
...
@@ -3710,20 +3661,13 @@ updateaccount() {
...
@@ -3710,20 +3661,13 @@ updateaccount() {
_initAPI
_initAPI
_email="$(_getAccountEmail)"
_email="$(_getAccountEmail)"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
if [ "$ACCOUNT_EMAIL" ]; then
if [ "$ACCOUNT_EMAIL" ]; then
updjson='{"contact": ["mailto:'$_email'"]}'
updjson='{"contact": ["mailto:'$_email'"]}'
else
else
updjson='{"contact": []}'
updjson='{"contact": []}'
fi
fi
else
# ACMEv1: Updates happen the same way a registration is done.
# https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-6.3
_regAccount
return
fi
# this part handles ACMEv2 account updates.
_send_signed_request "$_accUri" "$updjson"
_send_signed_request "$_accUri" "$updjson"
if [ "$code" = '200' ]; then
if [ "$code" = '200' ]; then
...
@@ -3768,11 +3712,8 @@ deactivateaccount() {
...
@@ -3768,11 +3712,8 @@ deactivateaccount() {
fi
fi
_initAPI
_initAPI
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_djson="{\"status\":\"deactivated\"}"
_djson="{\"status\":\"deactivated\"}"
else
_djson
=
"{
\"
resource
\"
:
\"
reg
\"
,
\"
status
\"
:
\"
deactivated
\"
}"
fi
if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then
if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then
_info "Deactivate account success for $_accUri."
_info "Deactivate account success for $_accUri."
_accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,')
_accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,')
...
@@ -3877,11 +3818,9 @@ __trigger_validation() {
...
@@ -3877,11 +3818,9 @@ __trigger_validation() {
_debug2 _t_key_authz "$_t_key_authz"
_debug2 _t_key_authz "$_t_key_authz"
_t_vtype="$3"
_t_vtype="$3"
_debug2 _t_vtype "$_t_vtype"
_debug2 _t_vtype "$_t_vtype"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_send_signed_request "$_t_url" "{}"
_send_signed_request "$_t_url" "{}"
else
_send_signed_request
"
$_t_url
"
"{
\"
resource
\"
:
\"
challenge
\"
,
\"
type
\"
:
\"
$_t_vtype
\"
,
\"
keyAuthorization
\"
:
\"
$_t_key_authz
\"
}"
fi
}
}
#endpoint domain type
#endpoint domain type
...
@@ -4297,7 +4236,6 @@ issue() {
...
@@ -4297,7 +4236,6 @@ issue() {
sep='#'
sep='#'
dvsep=','
dvsep=','
if [ -z "$vlist" ]; then
if [ -z "$vlist" ]; then
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
#make new order request
#make new order request
_identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}"
_identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}"
_w_index=1
_w_index=1
...
@@ -4364,7 +4302,6 @@ issue() {
...
@@ -4364,7 +4302,6 @@ issue() {
$_authorizations_map"
$_authorizations_map"
done
done
_debug2 _authorizations_map "$_authorizations_map"
_debug2 _authorizations_map "$_authorizations_map"
fi
_index=0
_index=0
_currentRoot=""
_currentRoot=""
...
@@ -4395,7 +4332,6 @@ $_authorizations_map"
...
@@ -4395,7 +4332,6 @@ $_authorizations_map"
vtype="$VTYPE_ALPN"
vtype="$VTYPE_ALPN"
fi
fi
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_idn_d="$(_idn "$d")"
_idn_d="$(_idn "$d")"
_candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")"
_candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")"
_debug2 _candidates "$_candidates"
_debug2 _candidates "$_candidates"
...
@@ -4416,13 +4352,6 @@ $_authorizations_map"
...
@@ -4416,13 +4352,6 @@ $_authorizations_map"
_on_issue_err "$_post_hook"
_on_issue_err "$_post_hook"
return 1
return 1
fi
fi
else
if
!
__get_domain_new_authz
"
$d
"
;
then
_clearup
_on_issue_err
"
$_post_hook
"
return
1
fi
fi
if [ -z "$thumbprint" ]; then
if [ -z "$thumbprint" ]; then
thumbprint="$(__calc_account_thumbprint)"
thumbprint="$(__calc_account_thumbprint)"
...
@@ -4462,11 +4391,9 @@ $_authorizations_map"
...
@@ -4462,11 +4391,9 @@ $_authorizations_map"
_on_issue_err "$_post_hook"
_on_issue_err "$_post_hook"
return 1
return 1
fi
fi
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)"
uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)"
else
uri
=
"
$(
echo
"
$entry
"
| _egrep_o
'"uri":"[^"]*'
|
cut
-d
'"'
-f
4
)
"
fi
_debug uri "$uri"
_debug uri "$uri"
if [ -z "$uri" ]; then
if [ -z "$uri" ]; then
...
@@ -4764,11 +4691,9 @@ $_authorizations_map"
...
@@ -4764,11 +4691,9 @@ $_authorizations_map"
_debug "sleep 2 secs to verify"
_debug "sleep 2 secs to verify"
sleep 2
sleep 2
_debug "checking"
_debug "checking"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_send_signed_request "$uri"
_send_signed_request "$uri"
else
response
=
"
$(
_get
"
$uri
"
)
"
fi
if [ "$?" != "0" ]; then
if [ "$?" != "0" ]; then
_err "$d:Verify error:$response"
_err "$d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
...
@@ -4833,7 +4758,6 @@ $_authorizations_map"
...
@@ -4833,7 +4758,6 @@ $_authorizations_map"
_info "Verify finished, start to sign."
_info "Verify finished, start to sign."
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)"
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_info "Lets finalize the order."
_info "Lets finalize the order."
_info "Le_OrderFinalize" "$Le_OrderFinalize"
_info "Le_OrderFinalize" "$Le_OrderFinalize"
if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then
if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then
...
@@ -4956,28 +4880,6 @@ $_authorizations_map"
...
@@ -4956,28 +4880,6 @@ $_authorizations_map"
done
done
fi
fi
fi
fi
else
if
!
_send_signed_request
"
${
ACME_NEW_ORDER
}
"
"{
\"
resource
\"
:
\"
$ACME_NEW_ORDER_RES
\"
,
\"
csr
\"
:
\"
$der
\"
}"
"needbase64"
;
then
_err
"Sign failed.
$response
"
_on_issue_err
"
$_post_hook
"
return
1
fi
_rcert
=
"
$response
"
Le_LinkCert
=
"
$(
grep
-i
'^Location.*$'
"
$HTTP_HEADER
"
| _tail_n 1 |
tr
-d
"
\r\n
"
|
cut
-d
" "
-f
2
)
"
echo
"
$BEGIN_CERT
"
>
"
$CERT_PATH
"
#if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then
# _debug "Get cert failed. Let's try last response."
# printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >> "$CERT_PATH"
#fi
if
!
printf
--
"%s"
"
$_rcert
"
| _dbase64
"multiline"
| _base64
"multiline"
>>
"
$CERT_PATH
"
;
then
_debug
"Try cert link."
_get
"
$Le_LinkCert
"
| _base64
"multiline"
>>
"
$CERT_PATH
"
fi
echo
"
$END_CERT
"
>>
"
$CERT_PATH
"
fi
_debug "Le_LinkCert" "$Le_LinkCert"
_debug "Le_LinkCert" "$Le_LinkCert"
_savedomainconf "Le_LinkCert" "$Le_LinkCert"
_savedomainconf "Le_LinkCert" "$Le_LinkCert"
...
@@ -5005,53 +4907,6 @@ $_authorizations_map"
...
@@ -5005,53 +4907,6 @@ $_authorizations_map"
fi
fi
fi
fi
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_debug
"v2 chain."
else
cp
"
$CERT_PATH
"
"
$CERT_FULLCHAIN_PATH
"
Le_LinkIssuer
=
$(
grep
-i
'^Link'
"
$HTTP_HEADER
"
| _head_n 1 |
cut
-d
" "
-f
2 |
cut
-d
';'
-f
1 |
tr
-d
'<>'
)
if
[
"
$Le_LinkIssuer
"
]
;
then
if
!
_contains
"
$Le_LinkIssuer
"
":"
;
then
_info
"
$(
__red
"Relative issuer link found."
)
"
Le_LinkIssuer
=
"
$_ACME_SERVER_HOST$Le_LinkIssuer
"
fi
_debug Le_LinkIssuer
"
$Le_LinkIssuer
"
_savedomainconf
"Le_LinkIssuer"
"
$Le_LinkIssuer
"
_link_issuer_retry
=
0
_MAX_ISSUER_RETRY
=
5
while
[
"
$_link_issuer_retry
"
-lt
"
$_MAX_ISSUER_RETRY
"
]
;
do
_debug _link_issuer_retry
"
$_link_issuer_retry
"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
if
_send_signed_request
"
$Le_LinkIssuer
"
;
then
echo
"
$response
"
>
"
$CA_CERT_PATH
"
break
fi
else
if
_get
"
$Le_LinkIssuer
"
>
"
$CA_CERT_PATH
.der"
;
then
echo
"
$BEGIN_CERT
"
>
"
$CA_CERT_PATH
"
_base64
"multiline"
<
"
$CA_CERT_PATH
.der"
>>
"
$CA_CERT_PATH
"
echo
"
$END_CERT
"
>>
"
$CA_CERT_PATH
"
if
!
_checkcert
"
$CA_CERT_PATH
"
;
then
_err
"Can not get the ca cert."
break
fi
cat
"
$CA_CERT_PATH
"
>>
"
$CERT_FULLCHAIN_PATH
"
rm
-f
"
$CA_CERT_PATH
.der"
break
fi
fi
_link_issuer_retry
=
$(
_math
$_link_issuer_retry
+ 1
)
_sleep
"
$_link_issuer_retry
"
done
if
[
"
$_link_issuer_retry
"
=
"
$_MAX_ISSUER_RETRY
"
]
;
then
_err
"Max retry for issuer ca cert is reached."
fi
else
_debug
"No Le_LinkIssuer header found."
fi
fi
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in $(__green " $CA_CERT_PATH ")"
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in $(__green " $CA_CERT_PATH ")"
[ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green " $CERT_FULLCHAIN_PATH ")"
[ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green " $CERT_FULLCHAIN_PATH ")"
...
@@ -5165,15 +5020,6 @@ renew() {
...
@@ -5165,15 +5020,6 @@ renew() {
. "$DOMAIN_CONF"
. "$DOMAIN_CONF"
_debug Le_API "$Le_API"
_debug Le_API "$Le_API"
if
[
"
$Le_API
"
=
"
$LETSENCRYPT_CA_V1
"
]
;
then
_cleardomainconf Le_API
Le_API
=
"
$DEFAULT_CA
"
fi
if
[
"
$Le_API
"
=
"
$LETSENCRYPT_STAGING_CA_V1
"
]
;
then
_cleardomainconf Le_API
Le_API
=
"
$DEFAULT_STAGING_CA
"
fi
if [ "$Le_API" ]; then
if [ "$Le_API" ]; then
export ACME_DIRECTORY="$Le_API"
export ACME_DIRECTORY="$Le_API"
#reload ca configs
#reload ca configs
...
@@ -5388,9 +5234,6 @@ signcsr() {
...
@@ -5388,9 +5234,6 @@ signcsr() {
return 1
return 1
fi
fi
if
[
-z
"
$ACME_VERSION
"
]
&&
_contains
"
$_csrsubj
,
$_csrdomainlist
"
"*."
;
then
export
ACME_VERSION
=
2
fi
_initpath "$_csrsubj" "$_csrkeylength"
_initpath "$_csrsubj" "$_csrkeylength"
mkdir -p "$DOMAIN_PATH"
mkdir -p "$DOMAIN_PATH"
...
@@ -5851,11 +5694,8 @@ revoke() {
...
@@ -5851,11 +5694,8 @@ revoke() {
_initAPI
_initAPI
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
data="{\"certificate\": \"$cert\",\"reason\":$_reason}"
data="{\"certificate\": \"$cert\",\"reason\":$_reason}"
else
data
=
"{
\"
resource
\"
:
\"
revoke-cert
\"
,
\"
certificate
\"
:
\"
$cert
\"
}"
fi
uri="${ACME_REVOKE_CERT}"
uri="${ACME_REVOKE_CERT}"
if [ -f "$CERT_KEY_PATH" ]; then
if [ -f "$CERT_KEY_PATH" ]; then
...
@@ -5926,7 +5766,6 @@ _deactivate() {
...
@@ -5926,7 +5766,6 @@ _deactivate() {
_d_type="$2"
_d_type="$2"
_initpath
_initpath
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}"
_identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}"
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
_err "Can not get domain new order."
_err "Can not get domain new order."
...
@@ -5955,20 +5794,6 @@ _deactivate() {
...
@@ -5955,20 +5794,6 @@ _deactivate() {
response="$(echo "$response" | _normalizeJson)"
response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response"
_debug2 response "$response"
_URL_NAME="url"
_URL_NAME="url"
else
if
!
__get_domain_new_authz
"
$_d_domain
"
;
then
_err
"Can not get domain new authz token."
return
1
fi
authzUri
=
"
$(
echo
"
$responseHeaders
"
|
grep
"^Location:"
| _head_n 1 |
cut
-d
':'
-f
2- |
tr
-d
"
\r\n
"
)
"
_debug
"authzUri"
"
$authzUri
"
if
[
"
$code
"
]
&&
[
!
"
$code
"
=
'201'
]
;
then
_err
"new-authz error:
$response
"
return
1
fi
_URL_NAME
=
"uri"
fi
entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")"
entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")"
if [ -z "$entries" ]; then
if [ -z "$entries" ]; then
...
@@ -6023,11 +5848,7 @@ _deactivate() {
...
@@ -6023,11 +5848,7 @@ _deactivate() {
_info "Deactivate: $_vtype"
_info "Deactivate: $_vtype"
if
[
"
$ACME_VERSION
"
=
"2"
]
;
then
_djson="{\"status\":\"deactivated\"}"
_djson="{\"status\":\"deactivated\"}"
else
_djson
=
"{
\"
resource
\"
:
\"
authz
\"
,
\"
status
\"
:
\"
deactivated
\"
}"
fi
if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then
if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then
_info "Deactivate: $_vtype success."
_info "Deactivate: $_vtype success."
...
@@ -7033,10 +6854,6 @@ _process() {
...
@@ -7033,10 +6854,6 @@ _process() {
return 1
return 1
fi
fi
if
_startswith
"
$_dvalue
"
"*."
;
then
_debug
"Wildcard domain"
export
ACME_VERSION
=
2
fi
if [ -z "$_domain" ]; then
if [ -z "$_domain" ]; then
_domain="$_dvalue"
_domain="$_dvalue"
else
else
...
...
deploy/synology_dsm.sh
View file @
130e8dbd
...
@@ -121,12 +121,6 @@ synology_dsm_deploy() {
...
@@ -121,12 +121,6 @@ synology_dsm_deploy() {
# we've verified this certificate description is a thing, so save it
# we've verified this certificate description is a thing, so save it
_savedeployconf SYNO_Certificate
"
$SYNO_Certificate
"
_savedeployconf SYNO_Certificate
"
$SYNO_Certificate
"
default
=
""
if
echo
"
$response
"
|
sed
-n
"s/.*
\"
desc
\"
:
\"
$SYNO_Certificate
\"
,
\(
[^{]*
\)
.*/
\1
/p"
|
grep
--
'is_default":true'
>
/dev/null
;
then
default
=
true
fi
_debug2 default
"
$default
"
_info
"Generate form POST request"
_info
"Generate form POST request"
nl
=
"
\0
015
\0
012"
nl
=
"
\0
015
\0
012"
delim
=
"--------------------------
$(
_utc_date |
tr
-d
--
'-: '
)
"
delim
=
"--------------------------
$(
_utc_date |
tr
-d
--
'-: '
)
"
...
@@ -135,7 +129,12 @@ synology_dsm_deploy() {
...
@@ -135,7 +129,12 @@ synology_dsm_deploy() {
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
inter_cert
\"
; filename=
\"
$(
basename
"
$_cca
"
)
\"
${
nl
}
Content-Type: application/octet-stream
${
nl
}${
nl
}
$(
cat
"
$_cca
"
)
\0
012"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
inter_cert
\"
; filename=
\"
$(
basename
"
$_cca
"
)
\"
${
nl
}
Content-Type: application/octet-stream
${
nl
}${
nl
}
$(
cat
"
$_cca
"
)
\0
012"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
id
\"
${
nl
}${
nl
}
$id
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
id
\"
${
nl
}${
nl
}
$id
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
desc
\"
${
nl
}${
nl
}${
SYNO_Certificate
}
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
desc
\"
${
nl
}${
nl
}${
SYNO_Certificate
}
"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
as_default
\"
${
nl
}${
nl
}${
default
}
"
if
echo
"
$response
"
|
sed
-n
"s/.*
\"
desc
\"
:
\"
$SYNO_Certificate
\"
,
\(
[^{]*
\)
.*/
\1
/p"
|
grep
--
'is_default":true'
>
/dev/null
;
then
_debug2 default
"this is the default certificate"
content
=
"
$content
${
nl
}
--
$delim
${
nl
}
Content-Disposition: form-data; name=
\"
as_default
\"
${
nl
}${
nl
}
true"
else
_debug2 default
"this is NOT the default certificate"
fi
content
=
"
$content
${
nl
}
--
$delim
--
${
nl
}
"
content
=
"
$content
${
nl
}
--
$delim
--
${
nl
}
"
content
=
"
$(
printf
"%b_"
"
$content
"
)
"
content
=
"
$(
printf
"%b_"
"
$content
"
)
"
content
=
"
${
content
%_
}
"
# protect trailing \n
content
=
"
${
content
%_
}
"
# protect trailing \n
...
...
dnsapi/dns_desec.sh
View file @
130e8dbd
...
@@ -20,21 +20,17 @@ dns_desec_add() {
...
@@ -20,21 +20,17 @@ dns_desec_add() {
_debug txtvalue
"
$txtvalue
"
_debug txtvalue
"
$txtvalue
"
DEDYN_TOKEN
=
"
${
DEDYN_TOKEN
:-
$(
_readaccountconf_mutable DEDYN_TOKEN
)
}
"
DEDYN_TOKEN
=
"
${
DEDYN_TOKEN
:-
$(
_readaccountconf_mutable DEDYN_TOKEN
)
}
"
DEDYN_NAME
=
"
${
DEDYN_NAME
:-
$(
_readaccountconf_mutable DEDYN_NAME
)
}
"
if
[
-z
"
$DEDYN_TOKEN
"
]
||
[
-z
"
$DEDYN_NAME
"
]
;
then
if
[
-z
"
$DEDYN_TOKEN
"
]
;
then
DEDYN_TOKEN
=
""
DEDYN_TOKEN
=
""
DEDYN_NAME
=
""
_err
"You did not specify DEDYN_TOKEN yet."
_err
"You did not specify DEDYN_TOKEN and DEDYN_NAME yet."
_err
"Please create your key and try again."
_err
"Please create your key and try again."
_err
"e.g."
_err
"e.g."
_err
"export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err
"export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err
"export DEDYN_NAME=foobar.dedyn.io"
return
1
return
1
fi
fi
#save the api token
and name
to the account conf file.
#save the api token to the account conf file.
_saveaccountconf_mutable DEDYN_TOKEN
"
$DEDYN_TOKEN
"
_saveaccountconf_mutable DEDYN_TOKEN
"
$DEDYN_TOKEN
"
_saveaccountconf_mutable DEDYN_NAME
"
$DEDYN_NAME
"
_debug
"First detect the root zone"
_debug
"First detect the root zone"
if
!
_get_root
"
$fulldomain
"
"
$REST_API
/"
;
then
if
!
_get_root
"
$fulldomain
"
"
$REST_API
/"
;
then
...
@@ -47,7 +43,7 @@ dns_desec_add() {
...
@@ -47,7 +43,7 @@ dns_desec_add() {
# Get existing TXT record
# Get existing TXT record
_debug
"Getting txt records"
_debug
"Getting txt records"
txtvalues
=
"
\"\\\"
$txtvalue
\\\"\"
"
txtvalues
=
"
\"\\\"
$txtvalue
\\\"\"
"
_desec_rest GET
"
$REST_API
/
$
DEDYN_NAME
/rrsets/
$_sub_domain
/TXT/"
_desec_rest GET
"
$REST_API
/
$
_domain
/rrsets/
$_sub_domain
/TXT/"
if
[
"
$_code
"
=
"200"
]
;
then
if
[
"
$_code
"
=
"200"
]
;
then
oldtxtvalues
=
"
$(
echo
"
$response
"
| _egrep_o
"
\"
records
\"
:
\\
[
\"\\
S*
\"\\
]"
|
cut
-d
:
-f
2 |
tr
-d
"[]
\\\\\"
"
|
sed
"s/,/ /g"
)
"
oldtxtvalues
=
"
$(
echo
"
$response
"
| _egrep_o
"
\"
records
\"
:
\\
[
\"\\
S*
\"\\
]"
|
cut
-d
:
-f
2 |
tr
-d
"[]
\\\\\"
"
|
sed
"s/,/ /g"
)
"
...
@@ -63,7 +59,7 @@ dns_desec_add() {
...
@@ -63,7 +59,7 @@ dns_desec_add() {
_info
"Adding record"
_info
"Adding record"
body
=
"[{
\"
subname
\"
:
\"
$_sub_domain
\"
,
\"
type
\"
:
\"
TXT
\"
,
\"
records
\"
:[
$txtvalues
],
\"
ttl
\"
:3600}]"
body
=
"[{
\"
subname
\"
:
\"
$_sub_domain
\"
,
\"
type
\"
:
\"
TXT
\"
,
\"
records
\"
:[
$txtvalues
],
\"
ttl
\"
:3600}]"
if
_desec_rest PUT
"
$REST_API
/
$
DEDYN_NAME
/rrsets/"
"
$body
"
;
then
if
_desec_rest PUT
"
$REST_API
/
$
_domain
/rrsets/"
"
$body
"
;
then
if
_contains
"
$response
"
"
$txtvalue
"
;
then
if
_contains
"
$response
"
"
$txtvalue
"
;
then
_info
"Added, OK"
_info
"Added, OK"
return
0
return
0
...
@@ -87,16 +83,13 @@ dns_desec_rm() {
...
@@ -87,16 +83,13 @@ dns_desec_rm() {
_debug txtvalue
"
$txtvalue
"
_debug txtvalue
"
$txtvalue
"
DEDYN_TOKEN
=
"
${
DEDYN_TOKEN
:-
$(
_readaccountconf_mutable DEDYN_TOKEN
)
}
"
DEDYN_TOKEN
=
"
${
DEDYN_TOKEN
:-
$(
_readaccountconf_mutable DEDYN_TOKEN
)
}
"
DEDYN_NAME
=
"
${
DEDYN_NAME
:-
$(
_readaccountconf_mutable DEDYN_NAME
)
}
"
if
[
-z
"
$DEDYN_TOKEN
"
]
||
[
-z
"
$DEDYN_NAME
"
]
;
then
if
[
-z
"
$DEDYN_TOKEN
"
]
;
then
DEDYN_TOKEN
=
""
DEDYN_TOKEN
=
""
DEDYN_NAME
=
""
_err
"You did not specify DEDYN_TOKEN yet."
_err
"You did not specify DEDYN_TOKEN and DEDYN_NAME yet."
_err
"Please create your key and try again."
_err
"Please create your key and try again."
_err
"e.g."
_err
"e.g."
_err
"export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err
"export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err
"export DEDYN_NAME=foobar.dedyn.io"
return
1
return
1
fi
fi
...
@@ -112,7 +105,7 @@ dns_desec_rm() {
...
@@ -112,7 +105,7 @@ dns_desec_rm() {
# Get existing TXT record
# Get existing TXT record
_debug
"Getting txt records"
_debug
"Getting txt records"
txtvalues
=
""
txtvalues
=
""
_desec_rest GET
"
$REST_API
/
$
DEDYN_NAME
/rrsets/
$_sub_domain
/TXT/"
_desec_rest GET
"
$REST_API
/
$
_domain
/rrsets/
$_sub_domain
/TXT/"
if
[
"
$_code
"
=
"200"
]
;
then
if
[
"
$_code
"
=
"200"
]
;
then
oldtxtvalues
=
"
$(
echo
"
$response
"
| _egrep_o
"
\"
records
\"
:
\\
[
\"\\
S*
\"\\
]"
|
cut
-d
:
-f
2 |
tr
-d
"[]
\\\\\"
"
|
sed
"s/,/ /g"
)
"
oldtxtvalues
=
"
$(
echo
"
$response
"
| _egrep_o
"
\"
records
\"
:
\\
[
\"\\
S*
\"\\
]"
|
cut
-d
:
-f
2 |
tr
-d
"[]
\\\\\"
"
|
sed
"s/,/ /g"
)
"
...
@@ -131,7 +124,7 @@ dns_desec_rm() {
...
@@ -131,7 +124,7 @@ dns_desec_rm() {
_info
"Deleting record"
_info
"Deleting record"
body
=
"[{
\"
subname
\"
:
\"
$_sub_domain
\"
,
\"
type
\"
:
\"
TXT
\"
,
\"
records
\"
:[
$txtvalues
],
\"
ttl
\"
:3600}]"
body
=
"[{
\"
subname
\"
:
\"
$_sub_domain
\"
,
\"
type
\"
:
\"
TXT
\"
,
\"
records
\"
:[
$txtvalues
],
\"
ttl
\"
:3600}]"
_desec_rest PUT
"
$REST_API
/
$
DEDYN_NAME
/rrsets/"
"
$body
"
_desec_rest PUT
"
$REST_API
/
$
_domain
/rrsets/"
"
$body
"
if
[
"
$_code
"
=
"200"
]
;
then
if
[
"
$_code
"
=
"200"
]
;
then
_info
"Deleted, OK"
_info
"Deleted, OK"
return
0
return
0
...
...
dnsapi/dns_porkbun.sh
View file @
130e8dbd
...
@@ -78,7 +78,7 @@ dns_porkbun_rm() {
...
@@ -78,7 +78,7 @@ dns_porkbun_rm() {
if
[
"
$count
"
=
"0"
]
;
then
if
[
"
$count
"
=
"0"
]
;
then
_info
"Don't need to remove."
_info
"Don't need to remove."
else
else
record_id
=
$(
echo
"
$response
"
|
tr
'{'
'\n'
|
grep
"
$txtvalue
"
|
cut
-d
,
-f1
|
cut
-d
:
-f2
|
tr
-d
\"
)
record_id
=
$(
echo
"
$response
"
|
tr
'{'
'\n'
|
grep
--
"
$txtvalue
"
|
cut
-d
,
-f1
|
cut
-d
:
-f2
|
tr
-d
\"
)
_debug
"record_id"
"
$record_id
"
_debug
"record_id"
"
$record_id
"
if
[
-z
"
$record_id
"
]
;
then
if
[
-z
"
$record_id
"
]
;
then
_err
"Can not get record id to remove."
_err
"Can not get record id to remove."
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment