2016-04-17 19:47:22 +08:00
|
|
|
#!/usr/bin/env sh
|
2016-04-25 20:01:37 +08:00
|
|
|
|
2019-04-29 22:11:25 +08:00
|
|
|
VER=2.8.2
|
2016-04-13 20:37:18 +08:00
|
|
|
|
2016-04-14 21:44:26 +08:00
|
|
|
PROJECT_NAME="acme.sh"
|
2016-04-13 20:37:18 +08:00
|
|
|
|
2016-04-14 21:44:26 +08:00
|
|
|
PROJECT_ENTRY="acme.sh"
|
|
|
|
|
|
|
|
PROJECT="https://github.com/Neilpang/$PROJECT_NAME"
|
2016-03-08 20:44:12 +08:00
|
|
|
|
2016-09-02 22:37:49 +08:00
|
|
|
DEFAULT_INSTALL_HOME="$HOME/.$PROJECT_NAME"
|
2019-03-13 20:42:02 +08:00
|
|
|
|
|
|
|
_WINDOWS_SCHEDULER_NAME="$PROJECT_NAME.cron"
|
|
|
|
|
2016-09-02 22:37:49 +08:00
|
|
|
_SCRIPT_="$0"
|
|
|
|
|
2019-04-29 22:13:54 +08:00
|
|
|
_SUB_FOLDER_NOTIFY="notify"
|
|
|
|
_SUB_FOLDER_DNSAPI="dnsapi"
|
|
|
|
_SUB_FOLDER_DEPLOY="deploy"
|
|
|
|
|
|
|
|
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
|
2016-09-02 22:37:49 +08:00
|
|
|
|
2018-01-06 12:45:24 +08:00
|
|
|
LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory"
|
|
|
|
LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory"
|
|
|
|
|
|
|
|
LETSENCRYPT_CA_V2="https://acme-v02.api.letsencrypt.org/directory"
|
|
|
|
LETSENCRYPT_STAGING_CA_V2="https://acme-staging-v02.api.letsencrypt.org/directory"
|
|
|
|
|
2019-03-12 21:16:15 +08:00
|
|
|
DEFAULT_CA=$LETSENCRYPT_CA_V2
|
|
|
|
DEFAULT_STAGING_CA=$LETSENCRYPT_STAGING_CA_V2
|
2017-12-07 21:32:17 +08:00
|
|
|
|
2016-11-13 21:47:58 +08:00
|
|
|
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
2016-09-20 19:08:02 +08:00
|
|
|
DEFAULT_ACCOUNT_EMAIL=""
|
2016-03-19 22:04:03 +08:00
|
|
|
|
2016-11-06 23:08:45 +08:00
|
|
|
DEFAULT_ACCOUNT_KEY_LENGTH=2048
|
|
|
|
DEFAULT_DOMAIN_KEY_LENGTH=2048
|
|
|
|
|
2016-11-22 21:43:42 +08:00
|
|
|
DEFAULT_OPENSSL_BIN="openssl"
|
|
|
|
|
2018-01-06 12:45:24 +08:00
|
|
|
_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org"
|
2017-06-17 17:15:37 +08:00
|
|
|
_OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org"
|
2016-03-08 20:44:12 +08:00
|
|
|
|
|
|
|
VTYPE_HTTP="http-01"
|
|
|
|
VTYPE_DNS="dns-01"
|
2018-12-18 19:28:38 +08:00
|
|
|
VTYPE_ALPN="tls-alpn-01"
|
2016-06-17 13:23:44 +08:00
|
|
|
|
2016-09-23 23:14:03 +08:00
|
|
|
LOCAL_ANY_ADDRESS="0.0.0.0"
|
|
|
|
|
2018-12-28 22:52:40 +08:00
|
|
|
DEFAULT_RENEW=60
|
2016-06-26 10:09:51 +08:00
|
|
|
|
2016-07-15 22:56:16 +08:00
|
|
|
DEFAULT_DNS_SLEEP=120
|
|
|
|
|
2016-09-23 22:35:13 +08:00
|
|
|
NO_VALUE="no"
|
|
|
|
|
2018-03-14 21:20:27 +08:00
|
|
|
W_DNS="dns"
|
2018-12-18 19:28:38 +08:00
|
|
|
W_ALPN="alpn"
|
2018-02-12 21:49:22 +08:00
|
|
|
DNS_ALIAS_PREFIX="="
|
2016-03-08 20:44:12 +08:00
|
|
|
|
2017-02-06 20:42:54 +08:00
|
|
|
MODE_STATELESS="stateless"
|
|
|
|
|
2016-08-07 10:21:27 +08:00
|
|
|
STATE_VERIFIED="verified_ok"
|
|
|
|
|
2017-02-13 23:29:37 +08:00
|
|
|
NGINX="nginx:"
|
2017-02-14 22:03:48 +08:00
|
|
|
NGINX_START="#ACME_NGINX_START"
|
|
|
|
NGINX_END="#ACME_NGINX_END"
|
2017-02-13 23:29:37 +08:00
|
|
|
|
2016-03-17 21:18:09 +08:00
|
|
|
BEGIN_CSR="-----BEGIN CERTIFICATE REQUEST-----"
|
|
|
|
END_CSR="-----END CERTIFICATE REQUEST-----"
|
|
|
|
|
|
|
|
BEGIN_CERT="-----BEGIN CERTIFICATE-----"
|
|
|
|
END_CERT="-----END CERTIFICATE-----"
|
|
|
|
|
2018-03-08 19:49:53 +08:00
|
|
|
CONTENT_TYPE_JSON="application/jose+json"
|
2016-06-18 11:29:28 +08:00
|
|
|
RENEW_SKIP=2
|
|
|
|
|
2019-03-05 21:05:10 +08:00
|
|
|
B64CONF_START="__ACME_BASE64__START_"
|
|
|
|
B64CONF_END="__ACME_BASE64__END_"
|
|
|
|
|
2016-08-13 19:22:25 +08:00
|
|
|
ECC_SEP="_"
|
|
|
|
ECC_SUFFIX="${ECC_SEP}ecc"
|
|
|
|
|
2016-09-25 21:58:59 +08:00
|
|
|
LOG_LEVEL_1=1
|
|
|
|
LOG_LEVEL_2=2
|
|
|
|
LOG_LEVEL_3=3
|
|
|
|
DEFAULT_LOG_LEVEL="$LOG_LEVEL_1"
|
|
|
|
|
2017-02-19 12:13:18 +08:00
|
|
|
DEBUG_LEVEL_1=1
|
|
|
|
DEBUG_LEVEL_2=2
|
|
|
|
DEBUG_LEVEL_3=3
|
|
|
|
DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1
|
|
|
|
DEBUG_LEVEL_NONE=0
|
|
|
|
|
2017-02-19 13:24:00 +08:00
|
|
|
HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)"
|
|
|
|
|
2017-02-11 21:15:36 +08:00
|
|
|
SYSLOG_ERROR="user.error"
|
2017-02-19 12:13:18 +08:00
|
|
|
SYSLOG_INFO="user.info"
|
2017-02-11 21:15:36 +08:00
|
|
|
SYSLOG_DEBUG="user.debug"
|
|
|
|
|
2017-02-19 12:13:18 +08:00
|
|
|
#error
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_ERROR=3
|
2017-02-19 12:13:18 +08:00
|
|
|
#info
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_INFO=6
|
2017-02-19 12:13:18 +08:00
|
|
|
#debug
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_DEBUG=7
|
2017-02-19 12:13:18 +08:00
|
|
|
#debug2
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_DEBUG_2=8
|
2017-02-19 12:13:18 +08:00
|
|
|
#debug3
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_DEBUG_3=9
|
2017-02-19 12:13:18 +08:00
|
|
|
|
2017-02-19 12:42:37 +08:00
|
|
|
SYSLOG_LEVEL_DEFAULT=$SYSLOG_LEVEL_ERROR
|
2017-02-19 12:13:18 +08:00
|
|
|
#none
|
|
|
|
SYSLOG_LEVEL_NONE=0
|
|
|
|
|
2019-04-29 22:13:54 +08:00
|
|
|
NOTIFY_LEVEL_DISABLE=0
|
|
|
|
NOTIFY_LEVEL_ERROR=1
|
|
|
|
NOTIFY_LEVEL_RENEW=2
|
|
|
|
NOTIFY_LEVEL_SKIP=3
|
|
|
|
|
|
|
|
NOTIFY_LEVEL_DEFAULT=$NOTIFY_LEVEL_RENEW
|
|
|
|
|
|
|
|
NOTIFY_MODE_BULK=0
|
|
|
|
NOTIFY_MODE_CERT=1
|
|
|
|
|
|
|
|
NOTIFY_MODE_DEFAULT=$NOTIFY_MODE_BULK
|
|
|
|
|
2016-09-25 21:58:59 +08:00
|
|
|
_DEBUG_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh"
|
2016-03-08 20:44:12 +08:00
|
|
|
|
2017-02-05 23:06:06 +08:00
|
|
|
_PREPARE_LINK="https://github.com/Neilpang/acme.sh/wiki/Install-preparations"
|
|
|
|
|
2017-02-06 20:42:54 +08:00
|
|
|
_STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode"
|
|
|
|
|
2018-02-10 10:45:29 +08:00
|
|
|
_DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode"
|
|
|
|
|
2018-03-21 20:30:52 +08:00
|
|
|
_DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode"
|
|
|
|
|
2019-04-29 22:13:54 +08:00
|
|
|
_NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify"
|
|
|
|
|
2017-08-22 20:27:13 +08:00
|
|
|
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
|
|
|
|
|
|
|
|
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
|
|
|
|
|
2018-03-21 20:30:52 +08:00
|
|
|
_DNS_MANUAL_ERROR="It seems that you are using dns manual mode. Read this link first: $_DNS_MANUAL_WIKI"
|
|
|
|
|
2016-09-06 19:37:41 +08:00
|
|
|
__INTERACTIVE=""
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ -t 1 ]; then
|
2016-09-06 19:37:41 +08:00
|
|
|
__INTERACTIVE="1"
|
|
|
|
fi
|
2016-04-17 17:33:08 +08:00
|
|
|
|
2016-08-13 19:22:25 +08:00
|
|
|
__green() {
|
2018-11-23 22:53:02 +08:00
|
|
|
if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
|
|
|
|
printf '\033[1;31;32m%b\033[0m' "$1"
|
|
|
|
return
|
2016-09-02 20:55:11 +08:00
|
|
|
fi
|
2017-04-05 20:54:53 +08:00
|
|
|
printf -- "%b" "$1"
|
2016-08-13 19:22:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
__red() {
|
2018-11-23 22:53:02 +08:00
|
|
|
if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
|
|
|
|
printf '\033[1;31;40m%b\033[0m' "$1"
|
|
|
|
return
|
2016-09-02 20:55:11 +08:00
|
|
|
fi
|
2017-04-05 20:54:53 +08:00
|
|
|
printf -- "%b" "$1"
|
2016-08-13 19:22:25 +08:00
|
|
|
}
|
2016-04-17 17:33:08 +08:00
|
|
|
|
2016-09-25 21:58:59 +08:00
|
|
|
_printargs() {
|
2018-03-14 09:52:58 +01:00
|
|
|
_exitstatus="$?"
|
2016-11-29 00:11:02 +08:00
|
|
|
if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then
|
|
|
|
printf -- "%s" "[$(date)] "
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ -z "$2" ]; then
|
2016-11-29 00:11:02 +08:00
|
|
|
printf -- "%s" "$1"
|
2016-08-13 19:22:25 +08:00
|
|
|
else
|
2016-11-29 00:11:02 +08:00
|
|
|
printf -- "%s" "$1='$2'"
|
2016-08-13 19:22:25 +08:00
|
|
|
fi
|
2016-09-25 21:58:59 +08:00
|
|
|
printf "\n"
|
2018-03-13 12:43:07 +01:00
|
|
|
# return the saved exit status
|
|
|
|
return "$_exitstatus"
|
2016-08-13 19:22:25 +08:00
|
|
|
}
|
|
|
|
|
2016-11-04 22:03:41 +08:00
|
|
|
_dlg_versions() {
|
|
|
|
echo "Diagnosis versions: "
|
2017-02-25 19:08:00 +08:00
|
|
|
echo "openssl:$ACME_OPENSSL_BIN"
|
2017-03-30 21:16:25 +08:00
|
|
|
if _exists "${ACME_OPENSSL_BIN:-openssl}"; then
|
|
|
|
${ACME_OPENSSL_BIN:-openssl} version 2>&1
|
2016-11-04 22:03:41 +08:00
|
|
|
else
|
2017-02-25 19:08:00 +08:00
|
|
|
echo "$ACME_OPENSSL_BIN doesn't exists."
|
2016-11-04 22:03:41 +08:00
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
|
2016-11-04 22:03:41 +08:00
|
|
|
echo "apache:"
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ "$_APACHECTL" ] && _exists "$_APACHECTL"; then
|
2017-03-03 22:03:19 +08:00
|
|
|
$_APACHECTL -V 2>&1
|
2016-11-04 22:03:41 +08:00
|
|
|
else
|
|
|
|
echo "apache doesn't exists."
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
|
2017-06-15 21:44:10 +08:00
|
|
|
echo "nginx:"
|
|
|
|
if _exists "nginx"; then
|
|
|
|
nginx -V 2>&1
|
|
|
|
else
|
|
|
|
echo "nginx doesn't exists."
|
|
|
|
fi
|
|
|
|
|
2017-09-01 23:01:37 +08:00
|
|
|
echo "socat:"
|
|
|
|
if _exists "socat"; then
|
|
|
|
socat -h 2>&1
|
2016-11-04 22:03:41 +08:00
|
|
|
else
|
2017-09-01 23:01:37 +08:00
|
|
|
_debug "socat doesn't exists."
|
2016-11-04 22:03:41 +08:00
|
|
|
fi
|
|
|
|
}
|
2016-08-13 19:22:25 +08:00
|
|
|
|
2017-02-11 21:15:36 +08:00
|
|
|
#class
|
|
|
|
_syslog() {
|
2018-03-14 09:52:58 +01:00
|
|
|
_exitstatus="$?"
|
2017-02-19 12:13:18 +08:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" = "$SYSLOG_LEVEL_NONE" ]; then
|
2017-02-11 21:15:36 +08:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
_logclass="$1"
|
|
|
|
shift
|
2017-04-30 16:29:20 +08:00
|
|
|
if [ -z "$__logger_i" ]; then
|
|
|
|
if _contains "$(logger --help 2>&1)" "-i"; then
|
|
|
|
__logger_i="logger -i"
|
|
|
|
else
|
|
|
|
__logger_i="logger"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
$__logger_i -t "$PROJECT_NAME" -p "$_logclass" "$(_printargs "$@")" >/dev/null 2>&1
|
2018-03-14 09:52:58 +01:00
|
|
|
return "$_exitstatus"
|
2017-02-11 21:15:36 +08:00
|
|
|
}
|
|
|
|
|
2016-09-25 21:58:59 +08:00
|
|
|
_log() {
|
|
|
|
[ -z "$LOG_FILE" ] && return
|
2016-11-09 20:45:57 +08:00
|
|
|
_printargs "$@" >>"$LOG_FILE"
|
2016-09-25 21:58:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_info() {
|
2017-02-19 12:13:18 +08:00
|
|
|
_log "$@"
|
2017-02-19 12:42:37 +08:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_INFO" ]; then
|
2017-02-19 12:13:18 +08:00
|
|
|
_syslog "$SYSLOG_INFO" "$@"
|
|
|
|
fi
|
2016-09-25 21:58:59 +08:00
|
|
|
_printargs "$@"
|
2016-03-08 20:44:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_err() {
|
2017-02-19 12:13:18 +08:00
|
|
|
_syslog "$SYSLOG_ERROR" "$@"
|
|
|
|
_log "$@"
|
2016-11-29 00:11:02 +08:00
|
|
|
if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then
|
|
|
|
printf -- "%s" "[$(date)] " >&2
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ -z "$2" ]; then
|
2016-09-28 13:13:08 +08:00
|
|
|
__red "$1" >&2
|
|
|
|
else
|
|
|
|
__red "$1='$2'" >&2
|
|
|
|
fi
|
2016-09-27 21:27:43 +08:00
|
|
|
printf "\n" >&2
|
2016-03-08 20:44:12 +08:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2016-08-13 19:22:25 +08:00
|
|
|
_usage() {
|
2016-11-09 19:30:39 +08:00
|
|
|
__red "$@" >&2
|
2016-09-28 13:13:08 +08:00
|
|
|
printf "\n" >&2
|
2016-08-13 19:22:25 +08:00
|
|
|
}
|
|
|
|
|
2016-03-19 18:18:34 +08:00
|
|
|
_debug() {
|
2017-02-19 12:13:18 +08:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_1" ]; then
|
|
|
|
_log "$@"
|
2016-09-25 21:58:59 +08:00
|
|
|
fi
|
2017-02-19 12:42:37 +08:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG" ]; then
|
2017-02-19 12:13:18 +08:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_1" ]; then
|
|
|
|
_printargs "$@" >&2
|
2016-03-19 18:18:34 +08:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 13:24:00 +08:00
|
|
|
#output the sensitive messages
|
|
|
|
_secure_debug() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_1" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_1" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-04-09 23:40:59 +08:00
|
|
|
_debug2() {
|
2017-02-19 12:13:18 +08:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_2" ]; then
|
|
|
|
_log "$@"
|
2016-09-25 21:58:59 +08:00
|
|
|
fi
|
2017-02-19 12:42:37 +08:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_2" ]; then
|
2017-02-19 12:13:18 +08:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then
|
2017-02-11 21:15:36 +08:00
|
|
|
_printargs "$@" >&2
|
2016-04-09 23:40:59 +08:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 13:24:00 +08:00
|
|
|
_secure_debug2() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_2" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_2" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_2" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-08-10 21:54:08 +08:00
|
|
|
_debug3() {
|
2017-02-19 12:13:18 +08:00
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_3" ]; then
|
|
|
|
_log "$@"
|
|
|
|
fi
|
2017-02-19 12:42:37 +08:00
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_3" ]; then
|
2017-02-19 12:13:18 +08:00
|
|
|
_syslog "$SYSLOG_DEBUG" "$@"
|
2016-09-25 21:58:59 +08:00
|
|
|
fi
|
2017-02-19 12:13:18 +08:00
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_3" ]; then
|
2017-02-11 21:15:36 +08:00
|
|
|
_printargs "$@" >&2
|
2016-08-10 21:54:08 +08:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-19 13:24:00 +08:00
|
|
|
_secure_debug3() {
|
|
|
|
if [ "${LOG_LEVEL:-$DEFAULT_LOG_LEVEL}" -ge "$LOG_LEVEL_3" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_log "$@"
|
|
|
|
else
|
|
|
|
_log "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ "${SYS_LOG:-$SYSLOG_LEVEL_NONE}" -ge "$SYSLOG_LEVEL_DEBUG_3" ]; then
|
|
|
|
_syslog "$SYSLOG_DEBUG" "$1" "$HIDDEN_VALUE"
|
|
|
|
fi
|
|
|
|
if [ "${DEBUG:-$DEBUG_LEVEL_NONE}" -ge "$DEBUG_LEVEL_3" ]; then
|
|
|
|
if [ "$OUTPUT_INSECURE" = "1" ]; then
|
|
|
|
_printargs "$@" >&2
|
|
|
|
else
|
|
|
|
_printargs "$1" "$HIDDEN_VALUE" >&2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-03-08 21:51:25 +08:00
|
|
|
_upper_case() {
|
|
|
|
# shellcheck disable=SC2018,SC2019
|
|
|
|
tr 'a-z' 'A-Z'
|
|
|
|
}
|
|
|
|
|
|
|
|
_lower_case() {
|
|
|
|
# shellcheck disable=SC2018,SC2019
|
|
|
|
tr 'A-Z' 'a-z'
|
|
|
|
}
|
|
|
|
|
2016-11-09 19:30:39 +08:00
|
|
|
_startswith() {
|
2016-04-16 21:52:24 +08:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
2016-05-13 21:14:00 +08:00
|
|
|
echo "$_str" | grep "^$_sub" >/dev/null 2>&1
|
2016-04-16 21:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-11-09 19:30:39 +08:00
|
|
|
_endswith() {
|
2016-08-13 19:22:25 +08:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
|
|
|
echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1
|
|
|
|
}
|
|
|
|
|
2016-11-09 19:30:39 +08:00
|
|
|
_contains() {
|
2016-04-16 21:52:24 +08:00
|
|
|
_str="$1"
|
|
|
|
_sub="$2"
|
2016-08-13 19:22:25 +08:00
|
|
|
echo "$_str" | grep -- "$_sub" >/dev/null 2>&1
|
2016-04-16 21:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-05-03 20:41:40 +08:00
|
|
|
_hasfield() {
|
|
|
|
_str="$1"
|
|
|
|
_field="$2"
|
|
|
|
_sep="$3"
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ -z "$_field" ]; then
|
2016-08-13 19:22:25 +08:00
|
|
|
_usage "Usage: str field [sep]"
|
2016-05-03 20:41:40 +08:00
|
|
|
return 1
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
|
|
|
|
if [ -z "$_sep" ]; then
|
2016-05-03 20:41:40 +08:00
|
|
|
_sep=","
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
|
2017-03-29 09:16:22 +08:00
|
|
|
for f in $(echo "$_str" | tr "$_sep" ' '); do
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ "$f" = "$_field" ]; then
|
2016-09-15 10:41:47 +08:00
|
|
|
_debug2 "'$_str' contains '$_field'"
|
2016-05-03 20:41:40 +08:00
|
|
|
return 0 #contains ok
|
|
|
|
fi
|
|
|
|
done
|
2016-09-15 10:41:47 +08:00
|
|
|
_debug2 "'$_str' does not contain '$_field'"
|
2017-04-17 19:08:34 +08:00
|
|
|
return 1 #not contains
|
2016-05-03 20:41:40 +08:00
|
|
|
}
|
|
|
|
|
2017-07-02 17:02:54 +08:00
|
|
|
# str index [sep]
|
2016-11-09 19:30:39 +08:00
|
|
|
_getfield() {
|
2016-09-23 23:14:03 +08:00
|
|
|
_str="$1"
|
|
|
|
_findex="$2"
|
|
|
|
_sep="$3"
|
2016-11-09 19:30:39 +08:00
|
|
|
|
|
|
|
if [ -z "$_findex" ]; then
|
2016-09-23 23:14:03 +08:00
|
|
|
_usage "Usage: str field [sep]"
|
|
|
|
return 1
|
|
|
|
fi
|
2016-11-09 19:30:39 +08:00
|
|
|
|
|
|
|
if [ -z "$_sep" ]; then
|
2016-09-23 23:14:03 +08:00
|
|
|
_sep=","
|
|
|
|
fi
|
|
|
|
|
2016-11-09 22:28:12 +08:00
|
|
|
_ffi="$_findex"
|
2016-11-09 19:30:39 +08:00
|
|
|
while [ "$_ffi" -gt "0" ]; do
|
2016-11-09 22:28:12 +08:00
|
|
|
_fv="$(echo "$_str" | cut -d "$_sep" -f "$_ffi")"
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ "$_fv" ]; then
|
2016-09-23 23:14:03 +08:00
|
|
|
printf -- "%s" "$_fv"
|
|
|
|
return 0
|
|
|
|
fi
|
2016-11-09 20:45:57 +08:00
|
|
|
_ffi="$(_math "$_ffi" - 1)"
|
2016-09-23 23:14:03 +08:00
|
|
|
done
|
2016-11-09 19:30:39 +08:00
|
|
|
|
2016-09-23 23:14:03 +08:00
|
|
|
printf -- "%s" "$_str"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-11-09 19:30:39 +08:00
|
|
|
_exists() {
|
2016-03-19 18:18:34 +08:00
|
|
|
cmd="$1"
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ -z "$cmd" ]; then
|
2016-08-13 19:22:25 +08:00
|
|
|
_usage "Usage: _exists cmd"
|
2016-03-19 18:18:34 +08:00
|
|
|
return 1
|
|
|
|
fi
|
2016-11-17 13:17:29 +08:00
|
|
|
|
|
|
|
if eval type type >/dev/null 2>&1; then
|
|
|
|
eval type "$cmd" >/dev/null 2>&1
|
|
|
|
elif command >/dev/null 2>&1; then
|
2016-05-13 21:14:00 +08:00
|
|
|
command -v "$cmd" >/dev/null 2>&1
|
2016-11-17 13:20:20 +08:00
|
|
|
else
|
2016-11-11 21:13:33 +08:00
|
|
|
which "$cmd" >/dev/null 2>&1
|
2016-04-16 19:38:11 +08:00
|
|
|
fi
|
2016-03-19 18:18:34 +08:00
|
|
|
ret="$?"
|
2016-08-25 10:45:41 +08:00
|
|
|
_debug3 "$cmd exists=$ret"
|
2016-03-19 18:18:34 +08:00
|
|
|
return $ret
|
|
|
|
}
|
|
|
|
|
2016-04-17 17:33:08 +08:00
|
|
|
#a + b
|
2016-11-09 19:30:39 +08:00
|
|
|
_math() {
|
2016-11-12 10:58:20 +08:00
|
|
|
_m_opts="$@"
|
|
|
|
printf "%s" "$(($_m_opts))"
|
2016-04-17 17:33:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_h_char_2_dec() {
|
|
|
|
_ch=$1
|
|
|
|
case "${_ch}" in
|
2016-11-09 19:30:39 +08:00
|
|
|
a | A)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "10"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
|
|
|
b | B)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "11"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
|
|
|
c | C)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "12"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
|
|
|
d | D)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "13"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
|
|
|
e | E)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "14"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
|
|
|
f | F)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "15"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
2016-04-17 17:33:08 +08:00
|
|
|
*)
|
2016-05-13 21:14:00 +08:00
|
|
|
printf "%s" "$_ch"
|
2016-11-09 19:30:39 +08:00
|
|
|
;;
|
2016-05-13 21:14:00 +08:00
|
|
|
esac
|
2016-04-17 17:33:08 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-08-14 22:37:21 +08:00
|
|
|
_URGLY_PRINTF=""
|
2016-11-09 19:30:39 +08:00
|
|
|
if [ "$(printf '\x41')" != 'A' ]; then
|
2016-08-14 22:37:21 +08:00
|
|
|
_URGLY_PRINTF=1
|
|
|
|
fi
|
|
|
|
|
2017-05-29 17:07:59 +08:00
|
|
|
_ESCAPE_XARGS=""
|
2017-06-23 18:11:11 +08:00
|
|
|
if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then
|
2017-05-29 17:07:59 +08:00
|
|
|
_ESCAPE_XARGS=1
|
|
|
|
fi
|
|
|
|
|
2016-03-08 20:44:12 +08:00
|
|
|
_h2b() {
|
2017-12-02 19:54:33 +08:00
|
|
|
if _exists xxd && xxd -r -p 2>/dev/null; then
|
2017-05-17 13:16:53 +08:00
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2016-03-08 20:44:12 +08:00
|
|
|
hex=$(cat)
|
2017-05-20 11:02:48 +08:00
|
|
|
ic=""
|
|
|
|
jc=""
|
2017-05-17 13:16:53 +08:00
|
|
|
_debug2 _URGLY_PRINTF "$_URGLY_PRINTF"
|
|
|
|
if [ -z "$_URGLY_PRINTF" ]; then
|
2017-05-29 17:07:59 +08:00
|
|
|
if [ "$_ESCAPE_XARGS" ] && _exists xargs; then
|
2017-05-20 11:02:48 +08:00
|
|
|
_debug2 "xargs"
|
2017-05-26 14:58:52 +08:00
|
|
|
echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/g' | xargs printf
|
2017-05-20 11:02:48 +08:00
|
|
|
else
|
2017-05-26 14:58:52 +08:00
|
|
|
for h in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\{2\}\)/ \1/g'); do
|
2017-05-20 11:02:48 +08:00
|
|
|
if [ -z "$h" ]; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
printf "\x$h%s"
|
|
|
|
done
|
|
|
|
fi
|
2017-05-17 13:16:53 +08:00
|
|
|
else
|
2017-05-26 14:58:52 +08:00
|
|
|
for c in $(echo "$hex" | _upper_case | sed 's/\([0-9A-F]\)/ \1/g'); do
|
2017-05-20 11:02:48 +08:00
|
|
|
if [ -z "$ic" ]; then
|
|
|
|
ic=$c
|
|
|
|
continue
|
2016-04-17 17:33:08 +08:00
|
|
|
fi
|
2017-05-20 11:02:48 +08:00
|
|
|
jc=$c
|
2016-05-13 21:14:00 +08:00
|
|
|
ic="$(_h_char_2_dec "$ic")"
|
|
|
|
jc="$(_h_char_2_dec "$jc")"
|
2016-11-11 22:00:15 +08:00
|
|
|
printf '\'"$(printf "%o" "$(_math "$ic" \* 16 + $jc)")""%s"
|
2017-05-20 11:02:48 +08:00
|
|
|
ic=""
|
|
|
|
jc=""
|
2017-05-17 13:16:53 +08:00
|
|
|
done
|
|
|
|
fi
|
2016-11-11 21:13:33 +08:00
|
|
|
|
2016-03-08 20:44:12 +08:00
|
|
|
}
|
|
|
|
|
2017-01-30 12:07:50 +08:00
|
|
|
_is_solaris() {
|
|
|
|
_contains "${__OS__:=$(uname -a)}" "solaris" || _contains "${__OS__:=$(uname -a)}" "SunOS"
|
|
|
|
}
|
|
|
|
|
2017-02-05 13:16:51 +08:00
|
|
|
#_ascii_hex str
|
|
|
|
#this can only process ascii chars, should only be used when od command is missing as a backup way.
|
|
|
|
_ascii_hex() {
|
|
|
|
_debug2 "Using _ascii_hex"
|
|
|
|
_str="$1"
|
|
|
|
_str_len=${#_str}
|
|
|
|
_h_i=1
|
|
|
|
while [ "$_h_i" -le "$_str_len" ]; do
|
|
|
|
_str_c="$(printf "%s" "$_str" | cut -c "$_h_i")"
|
|
|
|
printf " %02x" "'$_str_c"
|
|
|
|
_h_i="$(_math "$_h_i" + 1)"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2017-01-30 12:07:50 +08:00
|
|
|
#stdin output hexstr splited by one space
|
|
|
|
#input:"abc"
|
|
|
|
#output: " 61 62 63"
|
|
|
|
_hex_dump() {
|
2017-02-10 20:55:25 +08:00
|
|
|
if _exists od; then
|
|
|
|
od -A n -v -t x1 | tr -s " " | sed 's/ $//' | tr -d "\r\t\n"
|
|
|
|
elif _exists hexdump; then
|
|
|
|
_debug3 "using hexdump"
|
|
|
|
hexdump -v -e '/1 ""' -e '/1 " %02x" ""'
|
|
|
|
elif _exists xxd; then
|
|
|
|
_debug3 "using xxd"
|
|
|
|
xxd -ps -c 20 -i | sed "s/ 0x/ /g" | tr -d ",\n" | tr -s " "
|
|
|
|
else
|
|
|
|
_debug3 "using _ascii_hex"
|
2017-02-05 13:16:51 +08:00
|
|
|
str=$(cat)
|
|
|
|
_ascii_hex "$str"
|
|
|
|
fi
|
2017-01-30 12:07:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#url encode, no-preserved chars
|
|
|
|
#A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
|
|
|
#41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a
|
|
|
|
|
|
|
|
#a b c d e f g h i j k l m n o p q r s t u v w x y z
|
|
|
|
#61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a
|
|
|
|
|
|
|
|
#0 1 2 3 4 5 6 7 8 9 - _ . ~
|
|
|
|
#30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e
|
|
|
|
|
|
|
|
#stdin stdout
|
|
|
|
_url_encode() {
|
|
|
|
_hex_str=$(_hex_dump)
|
|
|
|
_debug3 "_url_encode"
|
|
|
|
_debug3 "_hex_str" "$_hex_str"
|
|
|
|
for _hex_code in $_hex_str; do
|
|
|
|
#upper case
|
|
|
|
case "${_hex_code}" in
|
2017-01-30 12:25:56 +08:00
|
|
|
"41")
|
|
|
|
printf "%s" "A"
|
|
|
|
;;
|
|
|
|
"42")
|
|
|
|
printf "%s" "B"
|
|
|
|
;;
|
|
|
|
"43")
|
|
|
|
printf "%s" "C"
|
|
|
|
;;
|
|
|
|
"44")
|
|
|
|
printf "%s" "D"
|
|
|
|
;;
|
|
|
|
"45")
|
|
|
|
printf "%s" "E"
|
|
|
|
;;
|
|
|
|
"46")
|
|
|
|
printf "%s" "F"
|
|
|
|
;;
|
|
|
|
"47")
|
|
|
|
printf "%s" "G"
|
|
|
|
;;
|
|
|
|
"48")
|
|
|
|
printf "%s" "H"
|
|
|
|
;;
|
|
|
|
"49")
|
|
|
|
printf "%s" "I"
|
|
|
|
;;
|
|
|
|
"4a")
|
|
|
|
printf "%s" "J"
|
|
|
|
;;
|
|
|
|
"4b")
|
|
|
|
printf "%s" "K"
|
|
|
|
;;
|
|
|
|
"4c")
|
|
|
|
printf "%s" "L"
|
|
|
|
;;
|
|
|
|
"4d")
|
|
|
|
printf "%s" "M"
|
|
|
|
;;
|
|
|
|
"4e")
|
|
|
|
printf "%s" "N"
|
|
|
|
;;
|
|
|
|
"4f")
|
|
|
|
printf "%s" "O"
|
|
|
|
;;
|
|
|
|
"50")
|
|
|
|
printf "%s" "P"
|
|
|
|
;;
|
|
|
|
"51")
|
|
|
|
printf "%s" "Q"
|
|
|
|
;;
|
|
|
|
"52")
|
|
|
|
printf "%s" "R"
|
|
|
|
;;
|
|
|
|
"53")
|
|
|
|
printf "%s" "S"
|
|
|
|
;;
|
|
|
|
"54")
|
|
|
|
printf "%s" "T"
|
|
|
|
;;
|
|
|
|
"55")
|
|
|
|
printf "%s" "U"
|
|
|
|
;;
|
|
|
|
"56")
|
|
|
|
printf "%s" "V"
|
|
|
|
;;
|
|
|
|
"57")
|
|
|
|
printf "%s" "W"
|
|
|
|
;;
|
|
|
|
"58")
|
|
|
|
printf "%s" "X"
|
|
|
|
;;
|
|
|
|
"59")
|
|
|
|
printf "%s" "Y"
|
|
|
|
;;
|
|
|
|
"5a")
|
|
|
|
printf "%s" "Z"
|
|
|
|
;;
|
|
|
|
|
|
|
|
#lower case
|
|
|
|
"61")
|
|
|
|
printf "%s" "a"
|
|
|
|
;;
|
|
|
|
"62")
|
|
|
|
printf "%s" "b"
|
|
|
|
;;
|
|
|
|
"63")
|
|
|
|
printf "%s" "c"
|
|
|
|
;;
|
|
|
|
"64")
|
|
|
|
printf "%s" "d"
|
|
|
|
;;
|
|
|
|
"65")
|
|
|
|
printf "%s" "e"
|
|
|
|
;;
|
|
|
|
"66")
|
|
|
|
printf "%s" "f"
|
|
|
|
;;
|
|
|
|
"67")
|
|
|
|
printf "%s" "g"
|
|
|
|
;;
|
|
|
|
"68")
|
|
|
|
printf "%s" "h"
|
|
|
|
;;
|
|
|
|
"69")
|
|
|
|
printf "%s" "i"
|
|
|
|
;;
|
|
|
|
"6a")
|
|
|
|
printf "%s" "j"
|
|
|
|
;;
|
|
|
|
"6b")
|
|
|
|
printf "%s" "k"
|
|
|
|
;;
|
|
|
|
"6c")
|
|
|
|
printf "%s" "l"
|
|
|
|
;;
|
|
|
|
"6d")
|
|
|
|
printf "%s" "m"
|
|
|
|
;;
|
|
|
|
"6e")
|
|
|
|
printf "%s" "n"
|
|
|
|
;;
|
|
|
|
"6f")
|
|
|
|
printf "%s" "o"
|
|
|
|
;;
|
|
|
|
"70")
|
|
|
|
printf "%s" "p"
|
|
|
|
;;
|
|
|
|
"71")
|
|
|
|
printf "%s" "q"
|
|
|
|
;;
|
|
|
|
"72")
|
|
|
|
printf "%s" "r"
|
|
|
|
;;
|
|
|
|
"73")
|
|
|
|
printf "%s" "s"
|
|
|
|
;;
|
|
|
|
"74")
|
|
|
|
printf "%s" "t"
|
|
|
|
;;
|
|
|
|
"75")
|
|
|
|
printf "%s" "u"
|
|
|
|
;;
|
|
|
|
"76")
|
|
|
|
printf "%s" "v"
|
|
|
|
;;
|
|
|
|
"77")
|
|
|
|
printf "%s" "w"
|
|
|
|
;;
|
|