blob: 11629cc055ac03c19942bc86cdaf437f6f68e1e3 [file] [log] [blame]
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SHELLDOC-IGNORE
DEPENDENCY_CHECK_ARGS=()
DEPENDENCY_CHECK_SUPPRESSION_FILES=()
DEPENDENCY_CHECK_EXCLUDES_PATTERNS=()
DEPENDENCY_CHECK_TIMER="0"
DEPENDENCY_CHECK_SEVERITIES=("High" "Medium" "Low")
DEPENDENCY_CHECK_SEVERITY="${DEPENDENCY_CHECK_SEVERITIES[0]}"
DEPENDENCY_CHECK_UPDATE=true
DEPENDENCY_CHECK_EXPERIMENTAL=false
DEPENDENCY_CHECK_MAVEN_GOAL=check
add_test_type dependency_check
## @audience private
function dependency_check_usage
{
yetus_add_option "--dependency-check=<path>" "path to the dependency-check executable"
yetus_add_option "--dependency-check-severity-threshold=<value>" "ignore findings with a 'highest severity' lower than this. default: ${DEPENDENCY_CHECK_SEVERITY}"
yetus_add_option "--dependency-check-suppression=<list>" "path(s) to suppression XML file(s). see https://s.apache.org/ahw7"
yetus_add_option "--dependency-check-excludes=<list>" "list of ant style exclusions"
yetus_add_option "--dependency-check-experimental" "enable experimental analyzers."
yetus_add_option "--dependency-check-no-updates" "suppress updates of CVE information"
yetus_add_option "--dependency-check-data-file=<path>" "path to local H2 database"
yetus_add_option "--dependency-check-db-connection-string=<string>" "iff shared db, jdbs connection string"
yetus_add_option "--dependency-check-db-driver-name=<classname>" "iff shared db, jdbc driver name"
yetus_add_option "--dependency-check-db-driver-jar=<path>" "iff shared db, driver jar path"
yetus_add_option "--dependency-check-db-username=<name>" "iff shared db, username"
yetus_add_option "--dependency-check-db-password=<passwor>" "iff shared db, password"
yetus_add_option "--dependency-check-maven-goal=<goal>" "iff maven build, the plugin goal to use. default: ${DEPENDENCY_CHECK_MAVEN_GOAL}"
}
## @audience private
function dependency_check_parse_args
{
declare i
for i in "$@"; do
case ${i} in
--dependency-check=*)
DEPENDENCY_CHECK=${i#*=}
;;
--dependency-check-severity-threshold=*)
DEPENDENCY_CHECK_SEVERITY=${i#*=}
;;
--dependency-check-suppression=*)
yetus_comma_to_array DEPENDENCY_CHECK_SUPPRESSION_FILES "${i#*=}"
;;
--dependency-check-excludes=*)
yetus_comma_to_array DEPENDENCY_CHECK_EXCLUDES_PATTERNS "${i#*=}"
;;
--dependency-check-experimental)
DEPENDENCY_CHECK_EXPERIMENTAL=true
;;
--dependency-check-no-updates)
DEPENDENCY_CHECK_UPDATE=false
;;
--dependency-check-data-file=*)
DEPENDENCY_CHECK_DATA_FILE=${i#*=}
;;
--dependency-check-db-connection-string=*)
DEPENDENCY_CHECK_DB_CONNECTION=${i#*=}
;;
--dependency-check-db-driver-name=*)
DEPENDENCY_CHECK_DB_DRIVER=${i#*=}
;;
--dependency-check-db-driver-jar=*)
DEPENDENCY_CHECK_DB_DRIVER_JAR=${i#*=}
;;
--dependency-check-db-username=*)
DEPENDENCY_CHECK_DB_USER=${i#*=}
;;
--dependency-check-db-password=*)
DEPENDENCY_CHECK_DB_PASSWORD=${i#*=}
;;
--dependency-check-maven-goal=*)
DEPENDENCY_CHECK_MAVEN_GOAL=${i#*=}
;;
esac
done
}
## @audience private
function dependency_check_filefilter
{
declare filename=$1
case ${BUILDTOOL} in
maven)
if [[ ${filename} =~ pom\.xml$ ]]; then
yetus_debug "tests/dependency_check: ${filename}"
add_test dependency_check
fi
;;
*)
add_test dependency_check
;;
esac
}
## @audience private
function dependency_check_precheck
{
declare dependency_check_version
if ! yetus_array_contains "${DEPENDENCY_CHECK_SEVERITY}" "${DEPENDENCY_CHECK_SEVERITIES[@]}" ; then
yetus_error "Dependency check doesn't know about severity level '${DEPENDENCY_CHECK_SEVERITY}'"
return 1
fi
case ${BUILDTOOL} in
maven)
if [ "${#DEPENDENCY_CHECK_EXCLUDES_PATTERNS[@]}" -gt 0 ]; then
yetus_error "dependency_check: The maven plugin doesn't support exclusion patterns."
return 1
fi
;;
*)
if ! verify_command "dependency_check" "${DEPENDENCY_CHECK}"; then
add_vote_table 0 dependency_check "dependency-check was not available."
delete_test dependency_check
return 0
fi
;;
esac
# Can't give both data file and db connection info
if [ -n "${DEPENDENCY_CHECK_DATA_FILE}" ] && [ -n "${DEPENDENCY_CHECK_DB_CONNECTION}" ]; then
yetus_debug "Both a local datafile and an external db were given on the cli, behavior of dependency-check isn't well defined."
fi
# finally let folks know what version they'll be dealing with.
dependency_check_version=$(${DEPENDENCY_CHECK} --noupdate --version 2>/dev/null | head -n 1 2>/dev/null)
add_footer_table dependency_check "version: ${dependency_check_version}"
}
## @audience private
function dependency_check_initialize
{
local -a filtered_severities
local -i severity_threshold
severity_threshold=$(yetus_array_index_of "DEPENDENCY_CHECK_SEVERITIES" "${DEPENDENCY_CHECK_SEVERITY}")
yetus_debug "Looking for severities in our list ranked up to ${severity_threshold}"
for key in "${!DEPENDENCY_CHECK_SEVERITIES[@]}"; do
if [ ! "${key}" -gt "${severity_threshold}" ]; then
filtered_severities=("${filtered_severities[@]}" "${DEPENDENCY_CHECK_SEVERITIES[${key}]}")
fi
done
yetus_debug "Given severity threshold of '${DEPENDENCY_CHECK_SEVERITY}' we'll look for: ${filtered_severities[*]}"
# The quotes here are important, because we want to match an entire CSV record
IFS=" " read -r -a DEPENDENCY_CHECK_LOG_FILTERS <<< "$(printf -- '-e "%s" ' "${filtered_severities[@]}")"
case ${BUILDTOOL} in
maven)
if [[ "${DEPENDENCY_CHECK_EXPERIMENTAL}" = "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DenableExperimental=true")
fi
if [[ "${DEPENDENCY_CHECK_UPDATE}" = "false" ]] || [[ "${OFFLINE}" == "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DautoUpdate=false")
fi
if [[ "${OFFLINE}" == "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DcentralAnalyzerEnabled=false")
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DnexusAnalyzerEnabled=false")
fi
if [ -n "${DEPENDENCY_CHECK_DATA_FILE}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DdataDirectory=${DEPENDENCY_CHECK_DATA_FILE}")
fi
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-Dformat=ALL")
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DversionCheckEnabled=false")
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DskipProvidedScope=true")
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DskipSystemScope=true")
if [ "${#DEPENDENCY_CHECK_SUPPRESSION_FILES[@]}" -gt 0 ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DsuppressionFiles=$(printf -- "%s," "${DEPENDENCY_CHECK_SUPPRESSION_FILES[@]}")")
fi
if [ -n "${DEPENDENCY_CHECK_DB_CONNECTION}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DconnectionString=${DEPENDENCY_CHECK_DB_CONNECTION}")
if [ -n "${DEPENDENCY_CHECK_DB_DRIVER}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DdatabaseDriverName=${DEPENDENCY_CHECK_DB_DRIVER}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_DRIVER_JAR}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DdatabaseDriverPath=${DEPENDENCY_CHECK_DB_DRIVER_JAR}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_USER}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DdatabaseUser=${DEPENDENCY_CHECK_DB_USER}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_PASSWORD}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "-DdatabasePassword=${DEPENDENCY_CHECK_DB_PASSWORD}")
fi
fi
;;
*)
if [[ "${DEPENDENCY_CHECK_EXPERIMENTAL}" = "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --enableExperimental)
fi
if [[ "${DEPENDENCY_CHECK_UPDATE}" = "false" ]] || [[ "${OFFLINE}" == "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --noupdate)
fi
if [[ "${OFFLINE}" == "true" ]]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --disableCentral)
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --disableNexus)
fi
if [ -n "${DEPENDENCY_CHECK_DATA_FILE}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --data "${DEPENDENCY_CHECK_DATA_FILE}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_CONNECTION}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --connectionString "${DEPENDENCY_CHECK_DB_CONNECTION}")
if [ -n "${DEPENDENCY_CHECK_DB_DRIVER}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --dbDriverName "${DEPENDENCY_CHECK_DB_DRIVER}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_DRIVER_JAR}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --dbDriverPath "${DEPENDENCY_CHECK_DB_DRIVER_JAR}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_USER}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --dbUser "${DEPENDENCY_CHECK_DB_USER}")
fi
if [ -n "${DEPENDENCY_CHECK_DB_PASSWORD}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --dbPassword "${DEPENDENCY_CHECK_DB_PASSWORD}")
fi
fi
if [ "${#DEPENDENCY_CHECK_SUPPRESSION_FILES[@]}" -gt 0 ]; then
local -a suppressions
IFS=" " read -r -a suppressions <<< "$(printf -- "--suppression '%s' " "${DEPENDENCY_CHECK_SUPPRESSION_FILES[@]}")"
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "${suppressions[@]}")
fi
if [ "${#DEPENDENCY_CHECK_EXCLUDES_PATTERNS[@]}" -gt 0 ]; then
local -a excludes
IFS=" " read -r -a excludes <<< "$(printf -- "--exclude '%s' " "${DEPENDENCY_CHECK_EXCLUDES_PATTERNS[@]}")"
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" "${excludes[@]}")
fi
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --format ALL)
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --project "${PROJECT_NAME}")
if [ -n "${BASEDIR}" ]; then
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --scan "${BASEDIR}")
else
DEPENDENCY_CHECK_ARGS=("${DEPENDENCY_CHECK_ARGS[@]}" --scan ".")
fi
;;
esac
}
## @audience private
function dependency_check_logfilter
{
declare input=$1
declare output=$2
# TODO we should be parsing CSV columns properly
yetus_debug "dependency_check: filtering out lines based on severities with '${DEPENDENCY_CHECK_LOG_FILTERS[*]}'"
"${GREP}" "${DEPENDENCY_CHECK_LOG_FILTERS[@]}" "${input}" > "${output}"
}
## @audience private
function dependency_check_postcompile
{
declare repostatus=$1
declare reports="dependency_check_${repostatus}.reports"
if ! verify_needed_test dependency_check; then
return 0
fi
big_console_header "Determining number of dependency concerns (${repostatus})"
start_clock
# Add our previously calculated time
if [[ "${repostatus}" != branch ]]; then
offset_clock "${DEPENDENCY_CHECK_TIMER}"
fi
mkdir "${PATCH_DIR}/${reports}"
case ${BUILDTOOL} in
maven)
# invoke on a specific version, because older ones don't support options we need
# like CSV report output.
# shellcheck disable=2046
echo_and_redirect "${PATCH_DIR}/dependency_check_${repostatus}.log" \
$(maven_executor) --batch-mode "${DEPENDENCY_CHECK_ARGS[@]}" \
"org.owasp:dependency-check-maven:3.1.2:${DEPENDENCY_CHECK_MAVEN_GOAL}"
if [ ! -f "${BASEDIR:-.}/target/dependency-check-report.csv" ]; then
yetus_debug "maven goal did not generate csv report"
add_vote_table 0 dependency_check "${BUILDMODEMSG} maven goal did not generate needed report"
return 1
fi
# TODO get the plugin to allow configuring the output directory to something other than the project build dir.
# TODO maybe use the archive functionality here?
mv "${BASEDIR:-.}/target/dependency-check-"*{csv,html,json,xml} "${PATCH_DIR}/${reports}/"
;;
*)
echo_and_redirect "${PATCH_DIR}/dependency_check_${repostatus}.log" \
"${DEPENDENCY_CHECK}" "${DEPENDENCY_CHECK_ARGS[@]}" \
--log "${PATCH_DIR}/dependency_check_${repostatus}.verbose.log" \
--out "${PATCH_DIR}/${reports}"
;;
esac
generic_logfilter dependency_check \
"${PATCH_DIR}/${reports}/dependency-check-report.csv" \
"${PATCH_DIR}/dependency_check_${repostatus}_filtered.csv"
if [[ "${repostatus}" = branch ]]; then
DEPENDENCY_CHECK_TIMER=$(stop_clock)
else
# shellcheck disable=SC2016
numPostpatch=$(wc -l < "${PATCH_DIR}/dependency_check_patch_filtered.csv")
# iff the branch report doesn't already exist, we must be in a qbt build via --empty-patch
if [ -f "${PATCH_DIR}/dependency_check_branch_filtered.csv" ]; then
calcdiffs \
"${PATCH_DIR}/dependency_check_branch_filtered.csv" \
"${PATCH_DIR}/dependency_check_patch_filtered.csv" \
dependency_check \
> "${PATCH_DIR}/diff-dependency-check.csv"
diffPostpatch=$(wc -l < "${PATCH_DIR}/diff-dependency-check.csv")
# shellcheck disable=SC2016
numPrepatch=$(wc -l < "${PATCH_DIR}/dependency_check_branch_filtered.csv")
else
numPrepatch=0
diffPostpatch="${numPostpatch}"
cp "${PATCH_DIR}/dependency_check_patch_filtered.csv" \
"${PATCH_DIR}/diff-dependency-check.csv"
fi
statstring=$(generic_calcdiff_status "${numPrepatch}" "${numPostpatch}" "${diffPostpatch}" )
if [[ ${diffPostpatch} -gt 0 ]] ; then
add_vote_table -1 dependency_check "${BUILDMODEMSG} ${statstring}"
add_footer_table dependency_check "@@BASE@@/diff-dependency-check.csv"
return 1
fi
add_vote_table +1 dependency_check "${BUILDMODEMSG} ${statstring}"
fi
return 0
}