123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- #!/bin/bash
-
- shellfu import jat_dump
- shellfu import preupg
- shellfu import preupg_fupath
- shellfu import xcase
-
- #shellcheck disable=SC2034
- {
- PREUPG__RULE="xccdf_preupg_rule_api_severity_check"
- PREUPG__UPATH="RHEL6_7/all-xccdf.xml"
- PREUPG__VALID_ES='0-15'
- T_MSCRIPT="RHEL6_7/api/severity/check"
- }
-
-
- # ...................... # #
- # CASE GENERATOR HELPERS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
- # '''''''''''''''''''''' # #
-
- dec_event() {
- #
- # Decode numerical event id
- #
- case $1 in
-
- # the prefix is collation class decorator; gen_eseq will
- # sort|uniq the result, so here you can define forced
- # order. (Due to uniq, this also means that events in same
- # class will be "squashed" into one if found.)
-
- # log messages
- #
- 0) echo ;;
- 1) echo A.log_debug;;
- 2) echo A.log_info ;;
- 3) echo A.log_error ;;
- 4) echo A.log_warning ;;
-
- # risks
- #
- 10) echo ;;
- 11) echo A.log_slight_risk ;;
- 12) echo A.log_medium_risk ;;
- 13) echo A.log_high_risk ;;
- 14) echo A.log_extreme_risk ;;
-
- # exits
- #
- 20) echo ;;
- 21) echo Z.exit_pass ;;
- 22) echo Z.exit_fail ;;
- 23) echo Z.exit_error ;;
- 24) echo Z.exit_not_applicable ;;
- 25) echo Z.exit_informational ;;
- 26) echo Z.exit_fixed ;;
- esac
- }
-
- echoln() {
- #
- # Echo each argument separately
- #
- for ln in "$@";
- do
- echo "$ln"
- done
- }
-
- mkesg() {
- #
- # Make event sequence generator
- #
- local patt=$1
- local eclass # event class
- echo -n 'echoln '
- grep -o . <<<"$patt" \
- | while read -r eclass;
- do
- case $eclass in
- m) echo -n 'm{0..4}' ;;
- r) echo -n 'm{10..14}' ;;
- x) echo -n 'x{20..28}' ;;
- esac
- done
- }
-
- gen_eseq() {
- #
- # Get all possible programs in pattern $1
- #
- # Usage: gen_eseq PATT
- #
- # The PATT has format C[C..], where C is a "event class" and can
- # be one of following:
- #
- # 'm' for log message,
- # 'r' for risk log,
- # 'x' for exit_* call,
- #
- # Result is all possible unique event sequences (one per line)
- # conforming to PATT, where:
- #
- # * order between 'm' and 'r' is not preserved,
- # * 'x' is always last,
- # * each event can happen at least zero times and at most that
- # many times how many times the class was seen.
- #
- # Few examples to shed some light. Programs generated by following
- # PATTs may have certain properties:
- #
- # * 'mrx' can have 0-1 log messages, 0-1 risks and 0-1 exits,
- # * 'mmrx' can have 0-2 log messages, 0-1 risks and 0-1 exits
- # * 'mrmx' is the same because log/risk order is not significant,
- # * 'mrxm' is still the same because 'x' is forced to be last,
- # * 'mrxx' would have 0-2 exit calls,
- #
- # Note that these are not real programs but just lists of events
- # (named as API functions just for convenience); you will have to
- # parse the list (comma-separated) and append arguments where needed.
- #
- local patt=$1 # event pattern
- local eseq # event id sequence
- local eid # event id
- local esg # sequence generator (makes use of '{..}' Bash syntax)
- esg=$(mkesg "$patt")
- eval "$esg" \
- | while read -r eseq;
- do
- grep -oE '[[:alpha:]][[:digit:]]+' <<<"$eseq" \
- | while read -0r eid;
- do
- dec_event "${eid:1}"
- done \
- | grep . \
- | sort \
- | uniq \
- | colrm 1 2 \
- | paste -sd,
- done \
- | grep . \
- | sort \
- | uniq
- }
-
-
- # ............. # #
- # SETUP HELPERS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
- # ''''''''''''' # #
-
- mkcode() {
- #
- # Make body of module
- #
- xcase__id \
- | tr , '\n' \
- | while read -r event;
- do
- case $event in
- log_*_risk) echo "$event risk.by.$event" ;;
- log_*) echo "$event message.from.$event" ;;
- exit_*) echo "$event" ;;
- esac
- done
- }
-
-
- # ............. # #
- # INTROSPECTION # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
- # ''''''''''''' # #
-
- risksort() {
- #
- # Sort risk log calls based on severity (decorated sort)
- #
- local call # the risk call
- local args # ... args (finally ignored)
- while read -r call args;
- do
- case $call in
- log_slight_risk) echo -n '1 ' ;;
- log_medium_risk) echo -n '2 ' ;;
- log_high_risk) echo -n '3 ' ;;
- log_extreme_risk) echo -n '4 ' ;;
- esac
- echo "$call $args"
- done \
- | sort -n \
- | cut -d' ' -f2
- }
-
- logmsort() {
- #
- # Sort log message calls based on severity (decorated sort)
- #
- local call # the log call
- local args # ... args (finally ignored)
- while read -r call args;
- do
- case $call in
- log_debug) echo -n '1 ' ;;
- log_info) echo -n '2 ' ;;
- log_warning) echo -n '3 ' ;;
- log_error) echo -n '4 ' ;;
- esac
- echo "$call $args"
- done \
- | sort -n \
- | cut -d' ' -f2
- }
-
- get_worst_risk() {
- grep '^log_[a-z]*_risk' "$T_MSCRIPT" \
- | risksort \
- | tail -1
- }
-
- get_first_exit() {
- grep ^exit_ "$T_MSCRIPT" \
- | head -1
- }
-
- get_risknum() {
- grep -c '^log_[a-z]*_risk' "$T_MSCRIPT"
- }
-
- get_worst_logm() {
- grep '^log_' "$T_MSCRIPT" \
- | grep -v '_risk\b' \
- | logmsort \
- | tail -1
- }
-
-
- # .............. # #
- # XCASE HANDLERS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
- # '''''''''''''' # #
-
- xcase__enum() {
- gen_eseq rx
- #FIXME: add larger modes such as 'rrx', 'mrx' or 'rxx'
- }
-
-
- xcase__setup() {
- {
- echo '[MODULE]'
- echo 'GROUP = api'
- echo 'NAME = severity'
- mkcode | sed 's/^/CODE = /'
- } > module.mdef
- preupg_fupath RHEL6_7 "module.mdef"
- }
-
- xcase__test() {
- local o_es # oracle: exit status
- local o_result # oracle: assessment result
-
- # set up oracles
- #
- case $(get_first_exit):$(get_worst_risk) in
- # obviously error
- #
- :*) o_es=2; o_result=error ;;
- exit_error:*) o_es=2; o_result=error ;;
-
- # valid calls to exit_fail
- #
- exit_fail:log_slight_risk) o_es=0; o_result=needs_inspection ;;
- exit_fail:log_medium_risk) o_es=0; o_result=needs_inspection ;;
- exit_fail:log_high_risk) o_es=1; o_result=needs_action ;;
- exit_fail:log_extreme_risk) o_es=2; o_result=fail ;;
-
- # (mostly in)valid calls to other exit_*
- #
- exit_pass:*) o_es=0; o_result=pass ;;
- exit_not_applicable:*) o_es=0; o_result=notapplicable ;;
- exit_informational:*) o_es=0; o_result=informational ;;
- exit_fixed:*) o_es=0; o_result=fixed ;;
- exit_fail:) o_es=2; o_result=fail ;;
-
- esac
-
- # run preupg
- #
- PREUPG__VALID_ES=$o_es \
- preupg__run1 --skip-common
- preupg__assert result "$o_result"
- }
-
- xcase__diag() {
- jat_dump__file module.mdef "$T_MSCRIPT"
- preupg__get_risks | jat_dump__pipe RESULT_RISKS
- preupg__get_node | jat_dump__pipe RESULT_NODE
- }
-
- xcase__cleanup() {
- jat__cmd rm -rf RHEL6_7
- preupg__rmresult
- }
-
-
- # ............ # #
- # MAIN() STUFF # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
- # '''''''''''' # #
-
- PREUPG__UPATH=@pass \
- preupg__Run1
- xcase__run
- preupg__Cleanup
|