Issue
Using the following bash script:
#!/bin/bash
export SSLPROTOCOL="-all +TLSv1.2"
export SSLCIPHERSUITE="HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128"
# Set with quotes on purpose for this question
SSLPROTOCOL_PATTERN="^([+-]{1}[[:alnum:]]{3}(v[[:digit:]]+(\.[[:digit:]]+)?)?[[:space:]]?)+$"
SSLCIPHERSUITE_PATTERN="^([!+\-]?[\-[:alnum:]]+:?)+$"
# $SSLCIPHERSUITE successfully validates if you pass regex directly
if ! [[ $SSLCIPHERSUITE =~ ^([!+\-]?[\-[:alnum:]]+:?)+$ ]]; then
echo "Doesn't match"
else
echo "Matches"
fi
validate() {
if ! [[ $1 =~ $2 ]]; then
echo "Parameter value '$1' does not match the pattern $2"
else
echo "Parameter value '$1' validated."
fi
}
# SSLPROTOCOL Passes when passing regex as argument to function.
validate "$SSLPROTOCOL" "$SSLPROTOCOL_PATTERN"
# $SSLCIPHERSUITE Does not pass when passing regex as argument to function.
validate "$SSLCIPHERSUITE" "$SSLCIPHERSUITE_PATTERN"
I get the output:
➜ bash simple-test.sh
Matches
Parameter value '-all +TLSv1.2' validated.
Parameter value 'HIGH:!aNULL:!MD5:!3DES:!CAMELLIA:!AES128' does not match the pattern ^([!+\-]?[\-[:alnum:]]+:?)+$
As the comments explain:
SSLCIPHERSUITE
validates against the regex successfully if you do it directlySSLCIPHERSUITE
does not validate if you pass the regex as an argument into a function.SSLPROTOCOL
, however, does validate when passed as an argument into the function.
I know that this will work if you remove the quotes for the SSLCIPHERSUITE_PATTERN
regex and escape the ()
characters, like so:
SSLCIPHERSUITE_PATTERN=^\([!+\-]?[\-[:alnum:]]+:?\)+$
My question is why? Why does SSLPROTOCOL_PATTERN
work originally and SSLCIPHERSUITE_PATTERN
does not? Why does one need no quotes and the other works fine with quotes?
Solution
You're escaping a character (-
) that shouldn't be escaped (and using the wrong type of quotes, though you can get away with it in this context). Use this instead:
SSLCIPHERSUITE_PATTERN='^([!+-]?[-[:alnum:]]+:?)+$'
To portably include -
in a bracket expression in any tool you must put it at the start or end of the bracket expression, where you already have it. In some tools you can put it elsewhere in the bracket expression but then have to escape it but YMMV doing that and there's no reason to do it.
As for why it works in:
if ! [[ $SSLCIPHERSUITE =~ ^([!+\-]?[\-[:alnum:]]+:?)+$ ]]; then
my guess is bash is consuming the escape when parsing the code before using the resultant regexp in the comparison, again you should remove the \
though.
The escapes are the real problem in this case but in general - always use single quotes around all strings (including scripts) unless you NEED double quotes or no quotes, see https://mywiki.wooledge.org/Quotes.
As for why you must not quote the literal regexp in the comparison, see https://unix.stackexchange.com/q/382054/133219.
Answered By - Ed Morton Answer Checked By - Cary Denson (WPSolving Admin)