Skip to content

Commit

Permalink
Make parsing on jail.conf more robust
Browse files Browse the repository at this point in the history
jail.conf has a few tricky things about it's format (such as supporting
variable expansion) so it is easiest to get jail to do the parsing for us.

The changes to get required changes to set as well as we no longer are calling
grep so that became a single awk script as well.
  • Loading branch information
cqexbesd committed Jul 24, 2022
1 parent c50e99b commit 21a0ce7
Showing 1 changed file with 66 additions and 21 deletions.
87 changes: 66 additions & 21 deletions usr/local/share/bastille/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ usage() {
error_exit "Usage: bastille config TARGET get|set propertyName [newValue]"
}

# we need jail(8) to parse the config file so it can expand variables etc
print_jail_conf() {

# we need to pass a literal \n to jail to get each parameter on its own
# line
jail -f "$1" -e '
'
}

# Handle special-case commands first.
case "$1" in
help|-h|--help)
Expand Down Expand Up @@ -71,23 +80,30 @@ for _jail in ${JAILS}; do
continue
fi

ESCAPED_PROPERTY=$(echo "${PROPERTY}" | sed 's/\./\\\./g')
MATCH_LINE=$(grep "^[[:blank:]]*${ESCAPED_PROPERTY}[[:blank:]=;]" "${FILE}" 2>/dev/null)
MATCH_FOUND=$?

if [ "${ACTION}" = 'get' ]; then
if [ "${MATCH_FOUND}" -ne 0 ]; then
warn "not set"
elif ! echo "${MATCH_LINE}" | grep '=' > /dev/null 2>&1; then
echo "enabled"
else
VALUE=$(echo "${MATCH_LINE}" | sed -E 's/.+= *(.+) *;$/\1/' 2>/dev/null)
if [ $? -ne 0 ]; then
error_notify "Failed to get value."
else
echo "${VALUE}"
fi
fi
print_jail_conf "${FILE}" | awk -F= -v property="${PROPERTY}" '
$1 == property {
# note that we have found the property
found = 1;
# check if there is a value for this property
if (NF == 2) {
# remove any quotes surrounding the string
sub(/^"/, "", $2);
sub(/"$/, "", $2);
print $2;
} else {
# no value, just the property name
print "enabled"
}
exit 0;
}
END {
# if we have not found anything we need to print a special
# string
if (! found) {
print("not set")
}
}'
else # Setting the value. -- cwells
if [ -n "${VALUE}" ]; then
VALUE=$(echo "${VALUE}" | sed 's/\//\\\//g')
Expand All @@ -99,11 +115,40 @@ for _jail in ${JAILS}; do
LINE=" ${PROPERTY};"
fi

if [ "${MATCH_FOUND}" -ne 0 ]; then # No match, so insert the property at the end. -- cwells
echo "$(awk -v line="${LINE}" '$0 == "}" { print line; } 1 { print $0; }' "${FILE}")" > "${FILE}"
else # Replace the existing value. -- cwells
sed -i '' -E "s/ *${ESCAPED_PROPERTY}[ =;].*/${LINE}/" "${FILE}"
fi
# add the value to the config file, replacing any existing value or, if
# there is none, at the end
#
# awk doesn't have "inplace" editing so we use a temp file
_tmpfile=$(mktemp) || error_exit "unable to set because mktemp failed"
cp "${FILE}" "${_tmpfile}" && \
awk -F= -v line="${LINE}" -v property="${PROPERTY}" '
BEGIN {
# build RE as string as we can not expand vars in RE literals
prop_re = "^[[:space:]]*" property "[[:space:]]*$";
}
$1 ~ prop_re && !found {
# we already have an entry in the config for this property so
# we need to substitute our line here rather than keep the
# existing line
print(line);
# note we have already found the property
found = 1;
# move onto the next line
next;
}
$1 == "}" {
# reached the end of the stanza so if we have not already
# added our line we need to do so now
if (! found) {
print(line);
}
}
{
# print each uninteresting line unchanged
print;
}
' "${_tmpfile}" > "${FILE}"
rm "${_tmpfile}"
fi
done

Expand Down

0 comments on commit 21a0ce7

Please sign in to comment.