summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2022-02-22 12:34:58 +0100
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2022-02-23 13:03:31 +0100
commita3da3c8a0b1113d941f837cce0615673b95fb9f2 (patch)
treeb20429167ccff6d9b647945a61451570140ab852 /scripts
parent8b7abe21e041d616ddb5a68652bc96e97b3eed44 (diff)
downloadmariadb-git-a3da3c8a0b1113d941f837cce0615673b95fb9f2.tar.gz
MDEV-26377: Stricter validation of ssl-mode values
This commit adds validation of the values of the ssl-mode parameter in SSL scripts, since now only a basic check for the presence of the "VERIFY_" prefix is performed there to detect "VERIFY_IDENTITY" and "VERIFY_CA", but all other values are not checked at all. In addition, this commit removes leading and trailing spaces from parameter values that SST scripts read from configuration files or from the command line so that they do not interfere with parameter checks and substitutions. Parameter substitution has been made more robust against characters in strings that the shell might erroneously interpret as regexp.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/wsrep_sst_common.sh91
-rw-r--r--scripts/wsrep_sst_mariabackup.sh26
-rw-r--r--scripts/wsrep_sst_rsync.sh30
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh26
4 files changed, 87 insertions, 86 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 6d4def74b86..d4d9a58897d 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -99,7 +99,6 @@ WSREP_SST_OPT_ADDR=""
WSREP_SST_OPT_ADDR_PORT=""
WSREP_SST_OPT_HOST=""
WSREP_SST_OPT_HOST_UNESCAPED=""
-WSREP_SST_OPT_HOST_ESCAPED=""
INNODB_DATA_HOME_DIR=$(trim_dir "${INNODB_DATA_HOME_DIR:-}")
INNODB_LOG_GROUP_HOME=$(trim_dir "${INNODB_LOG_GROUP_HOME:-}")
INNODB_UNDO_DIR=$(trim_dir "${INNODB_UNDO_DIR:-}")
@@ -122,20 +121,22 @@ case "$1" in
# without square brackets:
readonly WSREP_SST_OPT_HOST_UNESCAPED="${addr_no_bracket%%\]*}"
# Square brackets are needed in most cases:
- readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]"
- readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]"
+ readonly WSREP_SST_OPT_HOST="[$WSREP_SST_OPT_HOST_UNESCAPED]"
# Mark this address as IPv6:
readonly WSREP_SST_OPT_HOST_IPv6=1
+ # Let's remove the leading part that contains the host address:
+ remain="${WSREP_SST_OPT_ADDR#*\]}"
;;
*)
readonly WSREP_SST_OPT_HOST="${WSREP_SST_OPT_ADDR%%[:/]*}"
readonly WSREP_SST_OPT_HOST_UNESCAPED="$WSREP_SST_OPT_HOST"
- readonly WSREP_SST_OPT_HOST_ESCAPED="$WSREP_SST_OPT_HOST"
readonly WSREP_SST_OPT_HOST_IPv6=0
+ # Let's remove the leading part that contains the host address:
+ remain="${WSREP_SST_OPT_ADDR#*[:/]}"
;;
esac
- # Let's remove the leading part that contains the host address:
- remain="${WSREP_SST_OPT_ADDR#$WSREP_SST_OPT_HOST_ESCAPED}"
+ # If there is nothing but the address, then the remainder is empty:
+ [ "$remain" = "$WSREP_SST_OPT_ADDR" ] && remain=""
# Let's remove the ":" character that separates the port number
# from the hostname:
remain="${remain#:}"
@@ -143,39 +144,32 @@ case "$1" in
# up to "/" (if present):
WSREP_SST_OPT_ADDR_PORT="${remain%%/*}"
# If the "/" character is present, then the path is not empty:
- if [ "${remain#*/}" != "$remain" ]; then
+ if [ "$WSREP_SST_OPT_ADDR_PORT" != "$remain" ]; then
# This operation removes everything up to the "/" character,
# effectively removing the port number from the string:
readonly WSREP_SST_OPT_PATH="${remain#*/}"
else
readonly WSREP_SST_OPT_PATH=""
fi
- # The rest of the string is the same as the path (for now):
- remain="$WSREP_SST_OPT_PATH"
- # If there is one more "/" in the string, then everything before
- # it will be the module name, otherwise the module name is empty:
- if [ "${remain%%/*}" != "$remain" ]; then
- # This operation removes the tail after the very first
- # occurrence of the "/" character (inclusively):
- readonly WSREP_SST_OPT_MODULE="${remain%%/*}"
- else
- readonly WSREP_SST_OPT_MODULE=""
- fi
# Remove the module name part from the string, which ends with "/":
remain="${WSREP_SST_OPT_PATH#*/}"
- # If the rest of the string does not match the original, then there
- # was something else besides the module name:
+ # This operation removes the tail after the very first occurrence
+ # of the "/" character, inclusively:
+ readonly WSREP_SST_OPT_MODULE="${WSREP_SST_OPT_PATH%%/*}"
+ # If there is one more "/" in the string, then everything before
+ # it will be the LSN, otherwise the LSN is empty:
if [ "$remain" != "$WSREP_SST_OPT_PATH" ]; then
# Extract the part that matches the LSN by removing all
# characters starting from the very first "/":
readonly WSREP_SST_OPT_LSN="${remain%%/*}"
# Exctract everything after the first occurrence of
# the "/" character in the string:
+ source="$remain"
remain="${remain#*/}"
# If the remainder does not match the original string,
# then there is something else (the version number in
# our case):
- if [ "$remain" != "$WSREP_SST_OPT_LSN" ]; then
+ if [ "$remain" != "$source" ]; then
# Let's extract the version number by removing the tail
# after the very first occurence of the "/" character
# (inclusively):
@@ -238,14 +232,12 @@ case "$1" in
readonly WSREP_SST_OPT_HOST_UNESCAPED="${addr_no_bracket%%\]*}"
# Square brackets are needed in most cases:
readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]"
- readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]"
# Mark this address as IPv6:
readonly WSREP_SST_OPT_HOST_IPv6=1
;;
*)
readonly WSREP_SST_OPT_HOST="$2"
readonly WSREP_SST_OPT_HOST_UNESCAPED="$2"
- readonly WSREP_SST_OPT_HOST_ESCAPED="$2"
readonly WSREP_SST_OPT_HOST_IPv6=0
;;
esac
@@ -475,25 +467,25 @@ case "$1" in
;;
'--innodb-force-recovery')
if [ -n "$value" -a "$value" != "0" ]; then
- INNODB_FORCE_RECOVERY="$value"
+ INNODB_FORCE_RECOVERY=$(trim_string "$value")
fi
skip_mysqld_arg=1
;;
'--log-bin')
if [ -z "$WSREP_SST_OPT_BINLOG" ]; then
- MYSQLD_OPT_LOG_BIN="$value"
+ MYSQLD_OPT_LOG_BIN=$(trim_string "$value")
fi
skip_mysqld_arg=1
;;
'--log-bin-index')
if [ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then
- MYSQLD_OPT_LOG_BIN_INDEX="$value"
+ MYSQLD_OPT_LOG_BIN_INDEX=$(trim_string "$value")
fi
skip_mysqld_arg=1
;;
'--log-basename')
if [ -z "$WSREP_SST_OPT_LOG_BASENAME" ]; then
- MYSQLD_OPT_LOG_BASENAME="$value"
+ MYSQLD_OPT_LOG_BASENAME=$(trim_string "$value")
fi
skip_mysqld_arg=1
;;
@@ -678,27 +670,18 @@ if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then
# the corresponding variable:
readonly WSREP_SST_OPT_PORT="$WSREP_SST_OPT_ADDR_PORT"
fi
-elif [ -n "$WSREP_SST_OPT_ADDR" ]; then
+else
# If the port is missing, take the default port:
if [ -z "$WSREP_SST_OPT_PORT" ]; then
readonly WSREP_SST_OPT_PORT=4444
fi
WSREP_SST_OPT_ADDR_PORT="$WSREP_SST_OPT_PORT"
- # Let's remove the leading part that contains the host address:
- remain="${WSREP_SST_OPT_ADDR#$WSREP_SST_OPT_HOST_ESCAPED}"
- # Let's remove the ":" character that separates the port number
- # from the hostname:
- remain="${remain#:}"
- # Let's remove all characters upto first "/" character that
- # separates the hostname with port number from the path:
- remain="${remain#/}"
- # Let's construct a new value for the address with the port:
- WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_HOST:$WSREP_SST_OPT_PORT"
- if [ -n "$remain" ]; then
- WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_ADDR/$remain"
- fi
fi
+# Let's construct a new value for the address with the port:
+sst_path="${WSREP_SST_OPT_PATH:+/}$WSREP_SST_OPT_PATH"
+WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_HOST:$WSREP_SST_OPT_PORT$sst_path"
+
readonly WSREP_SST_OPT_ADDR
readonly WSREP_SST_OPT_ADDR_PORT
@@ -809,8 +792,11 @@ parse_cnf()
local group="${groups%%\|*}"
# Remove the remainder (the group name) from the rest
# of the groups list (as if it were a prefix):
- groups="${groups#$group}"
- groups="${groups#\|}"
+ if [ "$group" != "$groups" ]; then
+ groups="${groups#*\|}"
+ else
+ groups=""
+ fi
# If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
@@ -835,9 +821,11 @@ parse_cnf()
done
# Use default if we haven't found a value:
- if [ -z "$reval" ]; then
- [ -n "${3:-}" ] && reval="$3"
- fi
+ [ -z "$reval" ] && reval="${3:-}"
+
+ # Truncate spaces:
+ [ -n "$reval" ] && reval=$(trim_string "$reval")
+
if [ -n "$BASH_VERSION" ]; then
printf '%s' "$reval"
else
@@ -868,8 +856,11 @@ in_config()
local group="${groups%%\|*}"
# Remove the remainder (the group name) from the rest
# of the groups list (as if it were a prefix):
- groups="${groups#$group}"
- groups="${groups#\|}"
+ if [ "$group" != "$groups" ]; then
+ groups="${groups#*\|}"
+ else
+ groups=""
+ fi
# If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
@@ -1455,13 +1446,9 @@ check_server_ssl_config()
fi
fi
if [ -n "$tcert" ]; then
- tcert=$(trim_string "$tcert")
if [ "${tcert%/}" != "$tcert" -o -d "$tcert" ]; then
tcap="$tcert"
tcert=""
fi
fi
- if [ -n "$tcap" ]; then
- tcap=$(trim_string "$tcap")
- fi
}
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index a15a3f7b7a5..ce4001fdc56 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -40,7 +40,7 @@ tcert=""
tcap=""
tpem=""
tkey=""
-tmode='DISABLED'
+tmode=""
sockopt=""
progress=""
ttime=0
@@ -474,6 +474,15 @@ read_cnf()
tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \
tr [:lower:] [:upper:])
+ case "$tmode" in
+ 'VERIFY_IDENTITY'|'VERIFY_CA'|'REQUIRED'|'DISABLED')
+ ;;
+ *)
+ wsrep_log_error "Unrecognized ssl-mode option: '$tmode'"
+ exit 22 # EINVAL
+ ;;
+ esac
+
if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then
if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then
check_server_ssl_config
@@ -667,16 +676,13 @@ setup_ports()
#
wait_for_listen()
{
- local PORT="$1"
- local ADDR="$2"
- local MODULE="$3"
for i in {1..150}; do
- if check_port "" "$PORT" 'socat|nc'; then
+ if check_port "" "$SST_PORT" 'socat|nc'; then
break
fi
sleep 0.2
done
- echo "ready $ADDR/$MODULE//$sst_ver"
+ echo "ready $ADDR:$SST_PORT/$MODULE/$lsn/$sst_ver"
}
check_extra()
@@ -733,7 +739,7 @@ recv_joiner()
set +e
if [ $wait -ne 0 ]; then
- wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" &
+ wait_for_listen &
fi
timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
@@ -1179,7 +1185,7 @@ then
stagemsg='Joiner-Recv'
- MODULE='xtrabackup_sst'
+ MODULE="${WSREP_SST_OPT_MODULE:-xtrabackup_sst}"
[ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
@@ -1187,7 +1193,7 @@ then
[ -f "$DATA/xtrabackup_binary" ] && rm -f "$DATA/xtrabackup_binary"
[ -f "$DATA/xtrabackup_galera_info" ] && rm -f "$DATA/xtrabackup_galera_info"
- ADDR="$WSREP_SST_OPT_ADDR"
+ ADDR="$WSREP_SST_OPT_HOST"
if [ "${tmode#VERIFY}" != "$tmode" ]; then
# backward-incompatible behavior:
@@ -1201,7 +1207,7 @@ then
exit 42
fi
CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \
- tr ',' '\n' | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \
+ tr ',' '\n' | grep -F 'CN =' | cut -d '=' -f2 | sed s/^\ // | \
sed s/\ %//)
fi
MY_SECRET="$(wsrep_gen_secret)"
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 54160fd19a2..67a7afc638f 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -238,6 +238,15 @@ if [ -z "$SSLMODE" ]; then
elif [ -n "$SSTKEY" -a -n "$SSTCERT" ]; then
SSLMODE='REQUIRED'
fi
+else
+ case "$SSLMODE" in
+ 'VERIFY_IDENTITY'|'VERIFY_CA'|'REQUIRED'|'DISABLED')
+ ;;
+ *)
+ wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'"
+ exit 22 # EINVAL
+ ;;
+ esac
fi
if [ -n "$SSTKEY" -a -n "$SSTCERT" ]; then
@@ -262,18 +271,11 @@ VERIFY_OPT=""
CHECK_OPT=""
CHECK_OPT_LOCAL=""
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then
- case "$SSLMODE" in
- 'VERIFY_IDENTITY')
+ if [ "$SSLMODE" = 'VERIFY_IDENTITY' ]; then
VERIFY_OPT='verifyPeer = yes'
- ;;
- 'VERIFY_CA')
+ else
VERIFY_OPT='verifyChain = yes'
- ;;
- *)
- wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'"
- exit 22 # EINVAL
- ;;
- esac
+ fi
if [ -z "$SSTCA$SSTCAP" ]; then
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path"
exit 22 # EINVAL
@@ -338,7 +340,8 @@ while check_pid "$STUNNEL_PID" 1 "$STUNNEL_CONF"; do
sleep 1
done
-MODULE='rsync_sst'
+MODULE="${WSREP_SST_OPT_MODULE:-rsync_sst}"
+
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
@@ -650,7 +653,7 @@ elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then
check_sockets_utils
- ADDR="$WSREP_SST_OPT_ADDR"
+ ADDR="$WSREP_SST_OPT_HOST"
RSYNC_PORT="$WSREP_SST_OPT_PORT"
RSYNC_ADDR="$WSREP_SST_OPT_HOST"
RSYNC_ADDR_UNESCAPED="$WSREP_SST_OPT_HOST_UNESCAPED"
@@ -751,7 +754,7 @@ EOF
fi
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]; then
- # backward-incompatible behavior
+ # backward-incompatible behavior:
CN=""
if [ -n "$SSTCERT" ]; then
# find out my Common Name
@@ -770,7 +773,6 @@ EOF
ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST"
else
MY_SECRET="" # for check down in recv_joiner()
- ADDR="$WSREP_SST_OPT_HOST"
fi
until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID \
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index e7cd77396fe..747378aced8 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -41,7 +41,7 @@ tcert=""
tcap=""
tpem=""
tkey=""
-tmode='DISABLED'
+tmode=""
sockopt=""
progress=""
ttime=0
@@ -479,6 +479,15 @@ read_cnf()
tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | \
tr [:lower:] [:upper:])
+ case "$tmode" in
+ 'VERIFY_IDENTITY'|'VERIFY_CA'|'REQUIRED'|'DISABLED')
+ ;;
+ *)
+ wsrep_log_error "Unrecognized ssl-mode option: '$tmode'"
+ exit 22 # EINVAL
+ ;;
+ esac
+
if [ $encrypt -eq 0 -o $encrypt -ge 2 ]; then
if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ]; then
check_server_ssl_config
@@ -679,16 +688,13 @@ setup_ports()
#
wait_for_listen()
{
- local PORT="$1"
- local ADDR="$2"
- local MODULE="$3"
for i in {1..150}; do
- if check_port "" "$PORT" 'socat|nc'; then
+ if check_port "" "$SST_PORT" 'socat|nc'; then
break
fi
sleep 0.2
done
- echo "ready $ADDR/$MODULE//$sst_ver"
+ echo "ready $ADDR:$SST_PORT/$MODULE/$lsn/$sst_ver"
}
check_extra()
@@ -745,7 +751,7 @@ recv_joiner()
set +e
if [ $wait -ne 0 ]; then
- wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" &
+ wait_for_listen &
fi
timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
@@ -1206,7 +1212,7 @@ then
stagemsg='Joiner-Recv'
- MODULE='xtrabackup_sst'
+ MODULE="${WSREP_SST_OPT_MODULE:-xtrabackup_sst}"
[ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
@@ -1214,7 +1220,7 @@ then
[ -f "$DATA/xtrabackup_binary" ] && rm -f "$DATA/xtrabackup_binary"
[ -f "$DATA/xtrabackup_galera_info" ] && rm -f "$DATA/xtrabackup_galera_info"
- ADDR="$WSREP_SST_OPT_ADDR"
+ ADDR="$WSREP_SST_OPT_HOST"
if [ "${tmode#VERIFY}" != "$tmode" ]; then
# backward-incompatible behavior:
@@ -1228,7 +1234,7 @@ then
exit 42
fi
CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \
- tr ',' '\n' | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \
+ tr ',' '\n' | grep -F 'CN =' | cut -d '=' -f2 | sed s/^\ // | \
sed s/\ %//)
fi
MY_SECRET="$(wsrep_gen_secret)"