#!/bin/bash

# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Abort on error.
set -e

# Load common constants and variables.
. "$(dirname "$0")/common.sh"

# Given a kernel boot param string which includes ...dm="dmstuff"...
# this returns the dmstuff by itself.
get_dmparams() {
    echo "$1" | sed 's/^.*\ dm="\([^"]*\)".*/\1/'
}

# Given a kernel boot param string which includes ...dm="stuff"...
# this returns the param string with the dm="..." section removed.
# Useful in conjunction with get_dmparams to divide and process
# the two sections of parameters in seperate passes
kparams_remove_dm() {
    echo "$1" | sed 's/dm="[^"]*"//'
}

# Given a dm param string which includes dynamic values, return the
# same string with these values replaced by a magic string placeholder.
# This same magic placeholder is used in the config file, for comparison
# purposes.
dmparams_mangle() {
  local dmparams=$1
  # First handle new key-value style verity parameters.
  dmparams=$(echo "$dmparams" |
    sed -e 's/root_hexdigest=[0-9a-fA-F]*/root_hexdigest=MAGIC_HASH/' |
    sed -e 's/salt=[0-9a-fA-F]*/salt=MAGIC_SALT'/)
  # If we didn't substitute the MAGIC_HASH yet, these are the old
  # verity parameter format.
  if [[ $dmparams != *MAGIC_HASH* ]]; then
    dmparams=$(echo $dmparams | sed 's/sha1 [0-9a-fA-F]*/sha1 MAGIC_HASH/')
  fi
  # If we have bootcache enabled, replace its copy of the root_hexdigest
  # with MAGIC_HASH. The parameter is positional.
  if [[ $dmparams == *bootcache* ]]; then
    dmparams=$(echo $dmparams |
      sed -r 's:(bootcache (PARTUUID=)?%U(/PARTNROFF=|\+)1 [0-9]+) [0-9a-fA-F]+:\1 MAGIC_HASH:')
  fi
  echo $dmparams
}

# This escapes any non-alphanum character, since many such characters
# are regex metacharacters.
escape_regexmetas() {
    echo "$1" | sed 's/\([^a-zA-Z0-9]\)/\\\1/g'
}

usage() {
    echo "Usage $PROG image [config]"
}

main() {
    # We want to catch all the discrepancies, not just the first one.
    # So, any time we find one, we set testfail=1 and continue.
    # When finished we will use testfail to determine our exit value.
    local testfail=0
    # A buffer to include useful information that we dump when things fail.
    local output
    # Copy of a string before it has been through sed
    local pre_sed

    if [[ $# -ne 1 ]] && [[ $# -ne 2 ]]; then
        usage
        exit 1
    fi

    local image="$1"

    # A byte that should not appear in the command line to use as a sed
    # marker when doing regular expression replacements.
    local M=$'\001'

    # Default config location: same name/directory as this script,
    # with a .config file extension, ie ensure_secure_kernelparams.config.
    local configfile="$(dirname "$0")/${0/%.sh/.config}"
    # Or, maybe a config was provided on the command line.
    if [[ $# -eq 2 ]]; then
        configfile="$2"
    fi
    # Either way, load test-expectations data from config.
    . "$configfile" || return 1

    local kernelblob=$(make_temp_file)
    # TODO(jimhebert): Perform the kernel security tests on both the kernel
    #                  partitions. Here, we just run it on kernel partition 4
    #                  which is the install kernel on the recovery image.
    #                  crosbug.com/24274
    extract_image_partition "$image" 4 "$kernelblob"
    local rootfs=$(make_temp_dir)
    mount_image_partition_ro "$image" 3 "$rootfs"

    # Pick the right set of test-expectation data to use.
    local board=$(get_board_from_lsb_release "${rootfs}")
    eval "required_kparams=(\"\${required_kparams_$board[@]}\")"
    eval "required_kparams_regex=(\"\${required_kparams_regex_$board[@]}\")"
    eval "optional_kparams=(\"\${optional_kparams_$board[@]}\")"
    eval "optional_kparams_regex=(\"\${optional_kparams_regex_$board[@]}\")"
    eval "required_dmparams=(\"\${required_dmparams_$board[@]}\")"
    eval "required_dmparams_regex=(\"\${required_dmparams_regex_$board[@]}\")"
    output+="required_kparams=(\n"
    output+="$(printf "\t'%s'\n" "${required_kparams[@]}")\n)\n"
    output+="required_kparams_regex=(\n"
    output+="$(printf "\t'%s'\n" "${required_kparams_regex[@]}")\n)\n"
    output+="optional_kparams=(\n"
    output+="$(printf "\t'%s'\n" "${optional_kparams[@]}")\n)\n"
    output+="optional_kparams_regex=(\n"
    output+="$(printf "\t'%s'\n" "${optional_kparams_regex[@]}")\n)\n"
    output+="required_dmparams=(\n"
    output+="$(printf "\t'%s'\n" "${required_dmparams[@]}")\n)\n"
    output+="required_dmparams_regex=(\n"
    output+="$(printf "\t'%s'\n" "${required_dmparams_regex[@]}")\n)\n"

    # Divide the dm params from the rest and process seperately.
    local kparams=$(dump_kernel_config "$kernelblob")
    local dmparams=$(get_dmparams "$kparams")
    local kparams_nodm=$(kparams_remove_dm "$kparams")

    output+="\nkparams='${kparams}'\n"
    output+="\ndmparams='${dmparams}'\n"
    output+="\nkparams_nodm='${kparams_nodm}'\n"

    mangled_dmparams=$(dmparams_mangle "${dmparams}")
    output+="\nmangled_dmparams='${mangled_dmparams}'\n"
    # Special-case handling of the dm= param:
    testfail=1
    for expected_dmparams in "${required_dmparams[@]}"; do
      # Filter out all dynamic parameters.
      if [ "$mangled_dmparams" = "$expected_dmparams" ]; then
        testfail=0
        break
      fi
    done

    for expected_dmparams in "${required_dmparams_regex[@]}"; do
      if [[ -z $(echo "${mangled_dmparams}" | \
           sed "s${M}^${expected_dmparams}\$${M}${M}") ]]; then
        testfail=0
        break
      fi
    done

    if [ $testfail -eq 1 ]; then
        echo "Kernel dm= parameter does not match any expected values!"
        echo "Actual:   $dmparams"
        echo "Expected: ${required_dmparams[*]}"
        echo "Expected (regex): ${required_dmparams_regex[*]}"
    fi

    # Ensure all other required params are present.
    for param in "${required_kparams[@]}"; do
        if [[ "$kparams_nodm" != *$param* ]]; then
            echo "Kernel parameters missing required value: $param"
            testfail=1
        else
            # Remove matched params as we go. If all goes well, kparams_nodm
            # will be nothing left but whitespace by the end.
            param=$(escape_regexmetas "$param")
            kparams_nodm=$(echo " ${kparams_nodm} " |
                           sed "s${M} ${param} ${M} ${M}")
        fi
    done

    # Ensure all other required regex params are present.
    for param in "${required_kparams_regex[@]}"; do
      pre_sed=" ${kparams_nodm} "
      kparams_nodm=$(echo "${pre_sed}" | sed "s${M} ${param} ${M} ${M}")
      if [[ "${pre_sed}" == "${kparams_nodm}" ]]; then
        echo "Kernel parameters missing required value: ${param}"
        testfail=1
      fi
    done

    # Check-off each of the allowed-but-optional params that were present.
    for param in "${optional_kparams[@]}"; do
        param=$(escape_regexmetas "$param")
        kparams_nodm=$(echo " ${kparams_nodm} " |
                       sed "s${M} ${param} ${M} ${M}")
    done

    # Check-off each of the allowed-but-optional params that were present.
    for param in "${optional_kparams_regex[@]}"; do
        kparams_nodm=$(echo " ${kparams_nodm} " |
                       sed "s${M} ${param} ${M} ${M}")
    done

    # This section enforces the default-deny for any unexpected params
    # not already processed by one of the above loops.
    if [[ ! -z ${kparams_nodm// /} ]]; then
        echo "Unexpected kernel parameters found:"
        echo " $(echo "${kparams_nodm}" | sed -r 's:  +: :g')"
        testfail=1
    fi

    if [[ ${testfail} -eq 1 ]]; then
        echo "Debug output:"
        printf '%b\n' "${output}"
        echo "(actual error will be at the top of output)"
    fi

    exit $testfail
}

main $@
