Updating for Keylime release v7.12.1
This update brings the keylime-policy tool. Resolves: RHEL-75794 Signed-off-by: Sergio Correia <scorreia@redhat.com>
This commit is contained in:
parent
f0dcfc866f
commit
4742bca699
1
.gitignore
vendored
1
.gitignore
vendored
@ -33,3 +33,4 @@
|
||||
/v7.7.0.tar.gz
|
||||
/v7.8.0.tar.gz
|
||||
/v7.9.0.tar.gz
|
||||
/v7.12.1.tar.gz
|
||||
|
||||
@ -1,389 +0,0 @@
|
||||
--- a/scripts/create_runtime_policy.sh 2024-01-30 18:17:19.000000000 +0100
|
||||
+++ b/scripts/create_runtime_policy.sh 2024-08-16 17:25:50.871701853 +0200
|
||||
@@ -1,282 +1,155 @@
|
||||
-#!/usr/bin/env bash
|
||||
+#!/usr/bin/bash
|
||||
################################################################################
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2017 Massachusetts Institute of Technology.
|
||||
################################################################################
|
||||
|
||||
-
|
||||
-if [ $0 != "-bash" ] ; then
|
||||
- pushd `dirname "$0"` > /dev/null 2>&1
|
||||
-fi
|
||||
-KCRP_BASE_DIR=$(pwd)
|
||||
-if [ $0 != "-bash" ] ; then
|
||||
- popd 2>&1 > /dev/null
|
||||
-fi
|
||||
-KCRP_BASE_DIR=$KCRP_BASE_DIR/..
|
||||
-
|
||||
-function detect_hash {
|
||||
- local hashstr=$1
|
||||
-
|
||||
- case "${#hashstr}" in
|
||||
- 32) hashalgo=md5sum ;;
|
||||
- 40) hashalgo=sha1sum ;;
|
||||
- 64) hashalgo=sha256sum ;;
|
||||
- 128) hashalgo=sha512sum ;;
|
||||
- *) hashalgo="na";;
|
||||
- esac
|
||||
-
|
||||
- echo $hashalgo
|
||||
-}
|
||||
-
|
||||
-function announce {
|
||||
- # 1 - MESSAGE
|
||||
-
|
||||
- MESSAGE=$(echo "${1}" | tr '\n' ' ')
|
||||
- MESSAGE=$(echo $MESSAGE | sed "s/\t\t*/ /g")
|
||||
-
|
||||
- echo "==> $(date) - ${0} - $MESSAGE"
|
||||
-}
|
||||
-
|
||||
-function valid_algo {
|
||||
- local algo=$1
|
||||
-
|
||||
- [[ " ${ALGO_LIST[@]} " =~ " ${algo} " ]]
|
||||
-}
|
||||
-
|
||||
# Configure the installer here
|
||||
INITRAMFS_TOOLS_GIT=https://salsa.debian.org/kernel-team/initramfs-tools.git
|
||||
INITRAMFS_TOOLS_VER="master"
|
||||
|
||||
-# All defaults
|
||||
-ALGO=sha1sum
|
||||
-WORK_DIR=/tmp/kcrp
|
||||
-OUTPUT_DIR=${WORK_DIR}/output
|
||||
-ALLOWLIST_DIR=${WORK_DIR}/allowlist
|
||||
-INITRAMFS_LOC="/boot/"
|
||||
-INITRAMFS_STAGING_DIR=${WORK_DIR}/ima_ramfs/
|
||||
-INITRAMFS_TOOLS_DIR=${WORK_DIR}/initramfs-tools
|
||||
-BOOT_AGGREGATE_LOC="/sys/kernel/security/ima/ascii_runtime_measurements"
|
||||
-ROOTFS_LOC="/"
|
||||
-EXCLUDE_LIST="none"
|
||||
-SKIP_PATH="none"
|
||||
-ALGO_LIST=("sha1sum" "sha256sum" "sha512sum")
|
||||
+WORKING_DIR=$(readlink -f "$0")
|
||||
+WORKING_DIR=$(dirname "$WORKING_DIR")
|
||||
|
||||
# Grabs Debian's initramfs_tools from Git repo if no other options exist
|
||||
if [[ ! `command -v unmkinitramfs` && ! -x "/usr/lib/dracut/skipcpio" ]] ; then
|
||||
# Create temp dir for pulling in initramfs-tools
|
||||
- announce "INFO: Downloading initramfs-tools: $INITRAMFS_TOOLS_DIR"
|
||||
+ TMPDIR=`mktemp -d` || exit 1
|
||||
+ echo "INFO: Downloading initramfs-tools: $TMPDIR"
|
||||
|
||||
- mkdir -p $INITRAMFS_TOOLS_DIR
|
||||
# Clone initramfs-tools repo
|
||||
- pushd $INITRAMFS_TOOLS_DIR > /dev/null 2>&1
|
||||
- git clone $INITRAMFS_TOOLS_GIT initramfs-tools > /dev/null 2>&1
|
||||
- pushd initramfs-tools > /dev/null 2>&1
|
||||
- git checkout $INITRAMFS_TOOLS_VER > /dev/null 2>&1
|
||||
- popd > /dev/null 2>&1
|
||||
- popd > /dev/null 2>&1
|
||||
+ pushd $TMPDIR
|
||||
+ git clone $INITRAMFS_TOOLS_GIT initramfs-tools
|
||||
+ pushd initramfs-tools
|
||||
+ git checkout $INITRAMFS_TOOLS_VER
|
||||
+ popd # $TMPDIR
|
||||
+ popd
|
||||
|
||||
shopt -s expand_aliases
|
||||
- alias unmkinitramfs=$INITRAMFS_TOOLS_DIR/initramfs-tools/unmkinitramfs
|
||||
-
|
||||
- which unmkinitramfs > /dev/null 2>&1 || exit 1
|
||||
+ alias unmkinitramfs=$TMPDIR/initramfs-tools/unmkinitramfs
|
||||
fi
|
||||
|
||||
+
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
-USAGE=$(cat <<-END
|
||||
- Usage: $0 -o/--output_file FILENAME [-a/--algo ALGO] [-x/--ramdisk-location PATH] [-y/--boot_aggregate-location PATH] [-z/--rootfs-location PATH] [-e/--exclude_list FILENAME] [-s/--skip-path PATH] [-h/--help]
|
||||
+if [ $# -lt 1 ]
|
||||
+then
|
||||
+ echo "No arguments provided" >&2
|
||||
+ echo "Usage: `basename $0` -o [filename] -h [hash-algo]" >&2
|
||||
+ exit $NOARGS;
|
||||
+fi
|
||||
|
||||
- optional arguments:
|
||||
- -a/--algo (checksum algorithm to be used, default: $ALGO)
|
||||
- -x/--ramdisk-location (path to initramdisk, default: $INITRAMFS_LOC, set to "none" to skip)
|
||||
- -y/--boot_aggregate-location (path for IMA log, used for boot aggregate extraction, default: $BOOT_AGGREGATE_LOC, set to "none" to skip)
|
||||
- -z/--rootfs-location (path to root filesystem, default: $ROOTFS_LOC, cannot be skipped)
|
||||
- -e/--exclude_list (filename containing a list of paths to be excluded (i.e., verifier will not try to match checksums, default: $EXCLUDE_LIST)
|
||||
- -s/--skip-path (comma-separated path list, files found there will not have checksums calculated, default: $SKIP_PATH)
|
||||
- -h/--help (show this message and exit)
|
||||
-END
|
||||
-)
|
||||
+ALGO=sha256sum
|
||||
|
||||
-while [[ $# -gt 0 ]]
|
||||
-do
|
||||
- key="$1"
|
||||
+ALGO_LIST=("sha1sum" "sha256sum" "sha512sum")
|
||||
+
|
||||
+valid_algo() {
|
||||
+ local algo=$1
|
||||
|
||||
- case $key in
|
||||
- -a|--algo)
|
||||
- ALGO="$2"
|
||||
- shift
|
||||
- ;;
|
||||
- -a=*|--algo=*)
|
||||
- ALGO=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -x|--ramdisk-location)
|
||||
- INITRAMFS_LOC="$2"
|
||||
- shift
|
||||
- ;;
|
||||
- -x=*|--ramdisk-location=*)
|
||||
- INITRAMFS_LOC=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -y|--boot_aggregate-location)
|
||||
- BOOT_AGGREGATE_LOC=$2
|
||||
- shift
|
||||
- ;;
|
||||
- -y=*|--boot_aggregate-location=*)
|
||||
- BOOT_AGGREGATE_LOC=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -z|--rootfs-location)
|
||||
- ROOTFS_LOC=$2
|
||||
- shift
|
||||
- ;;
|
||||
- -z=*|--rootfs-location=*)
|
||||
- ROOTFS_LOC=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -e|--exclude_list)
|
||||
- EXCLUDE_LIST=$2
|
||||
- shift
|
||||
- ;;
|
||||
- -e=*|--exclude_list=*)
|
||||
- EXCLUDE_LIST=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -o=*|--output_file=*)
|
||||
- OUTPUT=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -o|--output_file)
|
||||
- OUTPUT=$2
|
||||
- shift
|
||||
- ;;
|
||||
- -s=*|--skip-path=*)
|
||||
- SKIP_PATH=$(echo $key | cut -d '=' -f 2)
|
||||
- ;;
|
||||
- -s|--skip-path)
|
||||
- SKIP_PATH=$2
|
||||
- shift
|
||||
- ;;
|
||||
- -h|--help)
|
||||
- printf "%s\n" "$USAGE"
|
||||
- exit 0
|
||||
- shift
|
||||
- ;;
|
||||
- *)
|
||||
- # unknown option
|
||||
- ;;
|
||||
- esac
|
||||
- shift
|
||||
+ [[ " ${ALGO_LIST[@]} " =~ " ${algo} " ]]
|
||||
+}
|
||||
+
|
||||
+while getopts ":o:h:" opt; do
|
||||
+ case $opt in
|
||||
+ o)
|
||||
+ OUTPUT=$(readlink -f $OPTARG)
|
||||
+ rm -f $OUTPUT
|
||||
+ ;;
|
||||
+ h)
|
||||
+ if valid_algo $OPTARG; then
|
||||
+ ALGO=$OPTARG
|
||||
+ else
|
||||
+ echo "Invalid hash function argument: use sha1sum, sha256sum, or sha512sum"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
done
|
||||
|
||||
-if ! valid_algo $ALGO
|
||||
+if [ ! "$OUTPUT" ]
|
||||
then
|
||||
- echo "Invalid hash function argument: pick from \"${ALGO_LIST[@]}\""
|
||||
+ echo "Missing argument for -o" >&2;
|
||||
+ echo "Usage: $0 -o [filename] -h [hash-algo]" >&2;
|
||||
exit 1
|
||||
fi
|
||||
|
||||
-if [[ -z $OUTPUT ]]
|
||||
-then
|
||||
- printf "%s\n" "$USAGE"
|
||||
- exit 1
|
||||
+
|
||||
+# Where to look for initramfs image
|
||||
+INITRAMFS_LOC="/boot"
|
||||
+if [ -d "/ostree" ]; then
|
||||
+ # If we are on an ostree system change where we look for initramfs image
|
||||
+ loc=$(grep -E "/ostree/[^/]([^/]*)" -o /proc/cmdline | head -n 1 | cut -d / -f 3)
|
||||
+ INITRAMFS_LOC="/boot/ostree/${loc}/"
|
||||
fi
|
||||
|
||||
-rm -rf $ALLOWLIST_DIR
|
||||
-rm -rf $INITRAMFS_STAGING_DIR
|
||||
-rm -rf $OUTPUT_DIR
|
||||
|
||||
-announce "Writing allowlist $ALLOWLIST_DIR/${OUTPUT} with $ALGO..."
|
||||
-mkdir -p $ALLOWLIST_DIR
|
||||
+echo "Writing allowlist to $OUTPUT with $ALGO..."
|
||||
|
||||
-if [[ $BOOT_AGGREGATE_LOC != "none" ]]
|
||||
-then
|
||||
- announce "--- Adding boot agregate from $BOOT_AGGREGATE_LOC on allowlist $ALLOWLIST_DIR/${OUTPUT} ..."
|
||||
# Add boot_aggregate from /sys/kernel/security/ima/ascii_runtime_measurements (IMA Log) file.
|
||||
# The boot_aggregate measurement is always the first line in the IMA Log file.
|
||||
# The format of the log lines is the following:
|
||||
# <PCR_ID> <PCR_Value> <IMA_Template> <File_Digest> <File_Name> <File_Signature>
|
||||
# File_Digest may start with the digest algorithm specified (e.g "sha1:", "sha256:") depending on the template used.
|
||||
- head -n 1 $BOOT_AGGREGATE_LOC | awk '{ print $4 " boot_aggregate" }' | sed 's/.*://' >> $ALLOWLIST_DIR/${OUTPUT}
|
||||
+head -n 1 /sys/kernel/security/ima/ascii_runtime_measurements | awk '{ print $4 " boot_aggregate" }' | sed 's/.*://' >> $OUTPUT
|
||||
|
||||
- bagghash=$(detect_hash $(cat $ALLOWLIST_DIR/${OUTPUT} | cut -d ' ' -f 1))
|
||||
- if [[ $ALGO != $bagghash ]]
|
||||
- then
|
||||
- announce "ERROR: \"boot aggregate\" has was calculated with $bagghash, but files will be calculated with $ALGO. Use option -a $bagghash"
|
||||
- exit 1
|
||||
- fi
|
||||
-else
|
||||
- announce "--- Skipping boot aggregate..."
|
||||
-fi
|
||||
-
|
||||
-announce "--- Adding all appropriate files from $ROOTFS_LOC on allowlist $ALLOWLIST_DIR/${OUTPUT} ..."
|
||||
# Add all appropriate files under root FS to allowlist
|
||||
-pushd $ROOTFS_LOC > /dev/null 2>&1
|
||||
-BASE_EXCLUDE_DIRS="\bsys\b\|\brun\b\|\bproc\b\|\blost+found\b\|\bdev\b\|\bmedia\b\|\bsnap\b\|\bmnt\b\|\bvar\b\|\btmp\b"
|
||||
-ROOTFS_FILE_LIST=$(ls | grep -v $BASE_EXCLUDE_DIRS)
|
||||
-if [[ $SKIP_PATH != "none" ]]
|
||||
-then
|
||||
- SKIP_PATH=$(echo $SKIP_PATH | sed -e "s#^$ROOTFS_LOC##g" -e "s#,$ROOTFS_LOC##g" -e "s#,#\\\|#g")
|
||||
- ROOTFS_FILE_LIST=$(echo "$ROOTFS_FILE_LIST" | grep -v "$SKIP_PATH")
|
||||
-fi
|
||||
-find $ROOTFS_FILE_LIST \( -fstype rootfs -o -xtype f -type l -o -type f \) -uid 0 -exec $ALGO "$ROOTFS_LOC/{}" >> $ALLOWLIST_DIR/${OUTPUT} \;
|
||||
-popd > /dev/null 2>&1
|
||||
+cd /
|
||||
+find `ls / | grep -v "\bsys\b\|\brun\b\|\bproc\b\|\blost+found\b\|\bdev\b\|\bmedia\b\|\bsnap\b\|mnt"` \( -fstype rootfs -o -xtype f -type l -o -type f \) -uid 0 -exec $ALGO '/{}' >> $OUTPUT \;
|
||||
|
||||
# Create staging area for init ram images
|
||||
-mkdir -p $INITRAMFS_STAGING_DIR
|
||||
-
|
||||
-if [[ $INITRAMFS_LOC != "none" ]]
|
||||
-then
|
||||
- # Where to look for initramfs image
|
||||
- if [[ -d "/ostree" ]]
|
||||
- then
|
||||
- X=$INITRAMFS_LOC
|
||||
- # If we are on an ostree system change where we look for initramfs image
|
||||
- loc=$(grep -E "/ostree/[^/]([^/]*)" -o /proc/cmdline | head -n 1 | cut -d / -f 3)
|
||||
- INITRAMFS_LOC="/boot/ostree/${loc}/"
|
||||
- announce "--- The location of initramfs was overriden from \"${X}\" to \"$INITRAMFS_LOC\""
|
||||
- fi
|
||||
+rm -rf /tmp/ima/
|
||||
+mkdir -p /tmp/ima
|
||||
|
||||
- announce "--- Creating allowlist for init ram disks found under \"$INITRAMFS_LOC\" to $ALLOWLIST_DIR/${OUTPUT} ..."
|
||||
- for i in $(ls ${INITRAMFS_LOC}/initr* 2> /dev/null)
|
||||
- do
|
||||
- announce " extracting $i"
|
||||
- mkdir -p $INITRAMFS_STAGING_DIR/$i-extracted
|
||||
- cd $INITRAMFS_STAGING_DIR/$i-extracted
|
||||
-
|
||||
- # platform-specific handling of init ram disk images
|
||||
- if [[ `command -v unmkinitramfs` ]] ; then
|
||||
- mkdir -p $INITRAMFS_STAGING_DIR/$i-extracted-unmk
|
||||
- unmkinitramfs $i $INITRAMFS_STAGING_DIR/$i-extracted-unmk
|
||||
- if [[ -d "$INITRAMFS_STAGING_DIR/$i-extracted-unmk/main/" ]] ; then
|
||||
- cp -r $INITRAMFS_STAGING_DIR/$i-extracted-unmk/main/. /tmp/ima/$i-extracted
|
||||
- else
|
||||
- cp -r $INITRAMFS_STAGING_DIR/$i-extracted-unmk/. /tmp/ima/$i-extracted
|
||||
- fi
|
||||
- elif [[ -x "/usr/lib/dracut/skipcpio" ]] ; then
|
||||
- /usr/lib/dracut/skipcpio $i | gunzip -c | cpio -i -d 2> /dev/null
|
||||
+# Iterate through init ram disks and add files to allowlist
|
||||
+echo "Creating allowlist for init ram disk"
|
||||
+for i in `ls ${INITRAMFS_LOC}/initr*`
|
||||
+do
|
||||
+ echo "extracting $i"
|
||||
+ mkdir -p /tmp/ima/$i-extracted
|
||||
+ cd /tmp/ima/$i-extracted
|
||||
+
|
||||
+ # platform-specific handling of init ram disk images
|
||||
+ if [[ `command -v unmkinitramfs` ]] ; then
|
||||
+ mkdir -p /tmp/ima/$i-extracted-unmk
|
||||
+ unmkinitramfs $i /tmp/ima/$i-extracted-unmk
|
||||
+ if [[ -d "/tmp/ima/$i-extracted-unmk/main/" ]] ; then
|
||||
+ cp -r /tmp/ima/$i-extracted-unmk/main/. /tmp/ima/$i-extracted
|
||||
else
|
||||
- announce "ERROR: No tools for initramfs image processing found!"
|
||||
- exit 1
|
||||
+ cp -r /tmp/ima/$i-extracted-unmk/. /tmp/ima/$i-extracted
|
||||
fi
|
||||
+ elif [[ -x "/usr/lib/dracut/skipcpio" ]] ; then
|
||||
+ /usr/lib/dracut/skipcpio $i | gunzip -c 2> /dev/null | cpio -i -d 2> /dev/null
|
||||
+ else
|
||||
+ echo "ERROR: No tools for initramfs image processing found!"
|
||||
+ break
|
||||
+ fi
|
||||
|
||||
- find -type f -exec $ALGO "./{}" \; | sed "s| \./\./| /|" >> $ALLOWLIST_DIR/${OUTPUT}
|
||||
- done
|
||||
-fi
|
||||
+ find -type f -exec $ALGO "./{}" \; | sed "s| \./\./| /|" >> $OUTPUT
|
||||
+done
|
||||
|
||||
-# Non-critical cleanup on the resulting file (when ROOTFS_LOC = '/', the path starts on allowlist ends up with double '//' )
|
||||
-sed -i "s^ //^ /^g" $ALLOWLIST_DIR/${OUTPUT}
|
||||
-# A bit of cleanup on the resulting file (among other problems, sha256sum might output a hash with the prefix '\\')
|
||||
-sed -i "s/^\\\//g" $ALLOWLIST_DIR/${OUTPUT}
|
||||
-
|
||||
-# Convert to runtime policy
|
||||
-mkdir -p $OUTPUT_DIR
|
||||
-announce "Converting created allowlist ($ALLOWLIST_DIR/${OUTPUT}) to Keylime runtime policy ($OUTPUT_DIR/${OUTPUT}) ..."
|
||||
-CONVERT_CMD_OPTS="--allowlist $ALLOWLIST_DIR/${OUTPUT} --output_file $OUTPUT_DIR/${OUTPUT}"
|
||||
-[ -f $EXCLUDE_LIST ] && CONVERT_CMD_OPTS="$CONVERT_CMD_OPTS --excludelist $EXCLUDE_LIST"
|
||||
-
|
||||
-pushd $KCRP_BASE_DIR > /dev/null 2>&1
|
||||
-export PYTHONPATH=$KCRP_BASE_DIR:$PYTHONPATH
|
||||
-# only 3 dependencies required: pip3 install cryptography lark packaging
|
||||
-python3 ./keylime/cmd/convert_runtime_policy.py $CONVERT_CMD_OPTS; echo " "
|
||||
-if [[ $? -eq 0 ]]
|
||||
-then
|
||||
- announce "Done, new runtime policy file present at ${OUTPUT_DIR}/$OUTPUT. It can be used on the tenant keylime host with \"keylime_tenant -c add --runtime-policy ${OUTPUT_DIR}/$OUTPUT <other options>"
|
||||
-fi
|
||||
-popd > /dev/null 2>&1
|
||||
+# when ROOTFS_LOC = '/', the path starts on allowlist ends up with double '//'
|
||||
+#
|
||||
+# Example:
|
||||
+#
|
||||
+# b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c //bar
|
||||
+#
|
||||
+# Replace the unwanted '//' with a single '/'
|
||||
+sed -i 's| /\+| /|g' ${OUTPUT}
|
||||
+
|
||||
+# When the file name contains newlines or backslashes, the output of sha256sum
|
||||
+# adds a backslash at the beginning of the line.
|
||||
+#
|
||||
+# Example:
|
||||
+#
|
||||
+# $ echo foo > ba\\r
|
||||
+# $ sha256sum ba\\r
|
||||
+# \b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c ba\\r
|
||||
+#
|
||||
+# Remove the unwanted backslash prefix
|
||||
+sed -i 's/^\\//g' ${OUTPUT}
|
||||
+
|
||||
+# Clean up
|
||||
+rm -rf /tmp/ima
|
||||
@ -1,168 +0,0 @@
|
||||
diff --git a/keylime/revocation_notifier.py b/keylime/revocation_notifier.py
|
||||
index 112012b8f..5724af486 100644
|
||||
--- a/keylime/revocation_notifier.py
|
||||
+++ b/keylime/revocation_notifier.py
|
||||
@@ -140,7 +140,7 @@ def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
|
||||
for i in range(config.getint("verifier", "max_retries")):
|
||||
next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
|
||||
try:
|
||||
- response = session.post(url, json=tosend, timeout=5)
|
||||
+ response = session.post(url, json=tosend, timeout=5, verify=requests.utils.DEFAULT_CA_BUNDLE_PATH)
|
||||
if response.status_code in [200, 202]:
|
||||
break
|
||||
|
||||
diff --git a/keylime/requests_client.py b/keylime/requests_client.py
|
||||
index 6da703264..16615f7d9 100644
|
||||
--- a/keylime/requests_client.py
|
||||
+++ b/keylime/requests_client.py
|
||||
@@ -1,3 +1,4 @@
|
||||
+import re
|
||||
import ssl
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
@@ -15,6 +16,10 @@ def __init__(
|
||||
ignore_hostname: bool = True,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
+ # Remove eventual "http?://" from the base url
|
||||
+ if base_url.startswith("http"):
|
||||
+ base_url = re.sub(r"https?://", "", base_url)
|
||||
+
|
||||
if tls_enabled:
|
||||
self.base_url = f"https://{base_url}"
|
||||
else:
|
||||
diff --git a/keylime/revocation_notifier.py b/keylime/revocation_notifier.py
|
||||
index 5724af486..5a7cc4b16 100644
|
||||
--- a/keylime/revocation_notifier.py
|
||||
+++ b/keylime/revocation_notifier.py
|
||||
@@ -9,8 +9,9 @@
|
||||
|
||||
import requests
|
||||
|
||||
-from keylime import config, crypto, json, keylime_logging
|
||||
+from keylime import config, crypto, json, keylime_logging, web_util
|
||||
from keylime.common import retry
|
||||
+from keylime.requests_client import RequestsClient
|
||||
|
||||
logger = keylime_logging.init_logging("revocation_notifier")
|
||||
broker_proc: Optional[Process] = None
|
||||
@@ -112,7 +113,10 @@ def worker(tosend: Dict[str, Any]) -> None:
|
||||
exponential_backoff = config.getboolean("verifier", "exponential_backoff")
|
||||
next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
|
||||
logger.debug(
|
||||
- "Unable to publish revocation message %d times, trying again in %f seconds: %s", i, next_retry, e
|
||||
+ "Unable to publish revocation message %d times, trying again in %f seconds: %s",
|
||||
+ i,
|
||||
+ next_retry,
|
||||
+ e,
|
||||
)
|
||||
time.sleep(next_retry)
|
||||
mysock.close()
|
||||
@@ -135,30 +139,50 @@ def notify_webhook(tosend: Dict[str, Any]) -> None:
|
||||
def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
|
||||
interval = config.getfloat("verifier", "retry_interval")
|
||||
exponential_backoff = config.getboolean("verifier", "exponential_backoff")
|
||||
- with requests.Session() as session:
|
||||
- logger.info("Sending revocation event via webhook...")
|
||||
- for i in range(config.getint("verifier", "max_retries")):
|
||||
- next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
|
||||
+
|
||||
+ max_retries = config.getint("verifier", "max_retries")
|
||||
+ if max_retries <= 0:
|
||||
+ logger.info("Invalid value found in 'max_retries' option for verifier, using default value")
|
||||
+ max_retries = 5
|
||||
+
|
||||
+ # Get TLS options from the configuration
|
||||
+ (cert, key, trusted_ca, key_password), verify_server_cert = web_util.get_tls_options(
|
||||
+ "verifier", is_client=True, logger=logger
|
||||
+ )
|
||||
+
|
||||
+ # Generate the TLS context using the obtained options
|
||||
+ tls_context = web_util.generate_tls_context(cert, key, trusted_ca, key_password, is_client=True, logger=logger)
|
||||
+
|
||||
+ logger.info("Sending revocation event via webhook to %s ...", url)
|
||||
+ for i in range(max_retries):
|
||||
+ next_retry = retry.retry_time(exponential_backoff, interval, i, logger)
|
||||
+
|
||||
+ with RequestsClient(
|
||||
+ url,
|
||||
+ verify_server_cert,
|
||||
+ tls_context,
|
||||
+ ) as client:
|
||||
try:
|
||||
- response = session.post(url, json=tosend, timeout=5, verify=requests.utils.DEFAULT_CA_BUNDLE_PATH)
|
||||
- if response.status_code in [200, 202]:
|
||||
- break
|
||||
-
|
||||
- logger.debug(
|
||||
- "Unable to publish revocation message %d times via webhook, "
|
||||
- "trying again in %d seconds. "
|
||||
- "Server returned status code: %s",
|
||||
- i,
|
||||
- next_retry,
|
||||
- response.status_code,
|
||||
- )
|
||||
- except requests.exceptions.RequestException as e:
|
||||
- logger.debug(
|
||||
- "Unable to publish revocation message %d times via webhook, trying again in %d seconds: %s",
|
||||
- i,
|
||||
- next_retry,
|
||||
- e,
|
||||
- )
|
||||
+ res = client.post("", json=tosend, timeout=5)
|
||||
+ except requests.exceptions.SSLError as ssl_error:
|
||||
+ if "TLSV1_ALERT_UNKNOWN_CA" in str(ssl_error):
|
||||
+ logger.warning(
|
||||
+ "Keylime does not recognize certificate from peer. Check if verifier 'trusted_server_ca' is configured correctly"
|
||||
+ )
|
||||
+
|
||||
+ raise ssl_error from ssl_error
|
||||
+
|
||||
+ if res and res.status_code in [200, 202]:
|
||||
+ break
|
||||
+
|
||||
+ logger.debug(
|
||||
+ "Unable to publish revocation message %d times via webhook, "
|
||||
+ "trying again in %d seconds. "
|
||||
+ "Server returned status code: %s",
|
||||
+ i + 1,
|
||||
+ next_retry,
|
||||
+ res.status_code,
|
||||
+ )
|
||||
|
||||
time.sleep(next_retry)
|
||||
|
||||
@@ -170,7 +194,11 @@ def worker_webhook(tosend: Dict[str, Any], url: str) -> None:
|
||||
cert_key = None
|
||||
|
||||
|
||||
-def process_revocation(revocation: Dict[str, Any], callback: Callable[[Dict[str, Any]], None], cert_path: str) -> None:
|
||||
+def process_revocation(
|
||||
+ revocation: Dict[str, Any],
|
||||
+ callback: Callable[[Dict[str, Any]], None],
|
||||
+ cert_path: str,
|
||||
+) -> None:
|
||||
global cert_key
|
||||
|
||||
if cert_key is None:
|
||||
@@ -182,10 +210,17 @@ def process_revocation(revocation: Dict[str, Any], callback: Callable[[Dict[str,
|
||||
cert_key = crypto.x509_import_pubkey(certpem)
|
||||
|
||||
if cert_key is None:
|
||||
- logger.warning("Unable to check signature of revocation message: %s not available", cert_path)
|
||||
+ logger.warning(
|
||||
+ "Unable to check signature of revocation message: %s not available",
|
||||
+ cert_path,
|
||||
+ )
|
||||
elif "signature" not in revocation or revocation["signature"] == "none":
|
||||
logger.warning("No signature on revocation message from server")
|
||||
- elif not crypto.rsa_verify(cert_key, revocation["msg"].encode("utf-8"), revocation["signature"].encode("utf-8")):
|
||||
+ elif not crypto.rsa_verify(
|
||||
+ cert_key,
|
||||
+ revocation["msg"].encode("utf-8"),
|
||||
+ revocation["signature"].encode("utf-8"),
|
||||
+ ):
|
||||
logger.error("Invalid revocation message siganture %s", revocation)
|
||||
else:
|
||||
message = json.loads(revocation["msg"])
|
||||
|
||||
24
keylime.spec
24
keylime.spec
@ -8,7 +8,7 @@
|
||||
%global selinuxtype targeted
|
||||
|
||||
Name: keylime
|
||||
Version: 7.9.0
|
||||
Version: 7.12.1
|
||||
Release: %autorelease
|
||||
Summary: Open source TPM software for Bootstrapping and Maintaining Trust
|
||||
|
||||
@ -18,17 +18,6 @@ Source1: %{srcname}.sysusers
|
||||
# The selinux policy for keylime is distributed via this repo: https://github.com/RedHat-SP-Security/keylime-selinux
|
||||
Source2: https://github.com/RedHat-SP-Security/%{name}-selinux/archive/v%{policy_version}/keylime-selinux-%{policy_version}.tar.gz
|
||||
|
||||
# Restore the create_allowlist.sh script
|
||||
# https://issues.redhat.com/browse/RHEL-32637
|
||||
Patch1: 0001-Restore-create-allowlist.patch
|
||||
# Use TLS for the revocation notification webhook
|
||||
# Take into account CA certificates added by configuration file
|
||||
# Include the system installed CA certificates
|
||||
# https://issues.redhat.com/browse/RHEL-49601
|
||||
# https://issues.redhat.com/browse/RHEL-51279
|
||||
# https://issues.redhat.com/browse/RHEL-51321
|
||||
Patch2: 0002-Use-TLS-on-revocation-webhook.patch
|
||||
|
||||
# Main program: Apache-2.0
|
||||
# Icons: MIT
|
||||
License: Apache-2.0 AND MIT
|
||||
@ -115,6 +104,7 @@ Requires: python3-gpg
|
||||
Requires: python3-lark-parser
|
||||
Requires: python3-pyasn1
|
||||
Requires: python3-pyasn1-modules
|
||||
requires: python3-psutil
|
||||
Requires: python3-jsonschema
|
||||
Requires: python3-typing-extensions
|
||||
Requires: tpm2-tools
|
||||
@ -226,14 +216,6 @@ for s in create_mb_refstate \
|
||||
%{buildroot}/%{_datadir}/%{srcname}/scripts/${s}
|
||||
done
|
||||
|
||||
# To keep the same functionality as in RHEL-9, install create_runtime_policy.sh
|
||||
# as create_allowlist.sh in RHEL-10
|
||||
# The convert_runtime_policy.py script to convert allowlist and excludelist into
|
||||
# runtime policy is not called anymore.
|
||||
# See: https://issues.redhat.com/browse/RHEL-11866
|
||||
install -Dpm 755 scripts/create_runtime_policy.sh \
|
||||
%{buildroot}/%{_datadir}/%{srcname}/scripts/create_allowlist.sh
|
||||
|
||||
# Ship configuration templates.
|
||||
cp -r ./templates %{buildroot}%{_datadir}/%{srcname}/templates/
|
||||
|
||||
@ -382,6 +364,7 @@ fi
|
||||
%{_bindir}/keylime_convert_runtime_policy
|
||||
%{_bindir}/keylime_create_policy
|
||||
%{_bindir}/keylime_sign_runtime_policy
|
||||
%{_bindir}/keylime-policy
|
||||
|
||||
|
||||
%files tools
|
||||
@ -400,7 +383,6 @@ fi
|
||||
%attr(400,%{srcname},%{srcname}) %{_sharedstatedir}/%{srcname}/tpm_cert_store/*.pem
|
||||
%{_tmpfilesdir}/%{srcname}.conf
|
||||
%{_sysusersdir}/%{srcname}.conf
|
||||
%{_datadir}/%{srcname}/scripts/create_allowlist.sh
|
||||
%{_datadir}/%{srcname}/scripts/ek-openssl-verify
|
||||
%{_datadir}/%{srcname}/templates
|
||||
%{_bindir}/keylime_upgrade_config
|
||||
|
||||
2
sources
2
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (v7.9.0.tar.gz) = 2f58ade2012f2be99d0a9d59c35562b8af91945d6f4c3dfcecfcac6e6603f36d819063796a6b7958c816c90da1d3a80e4b111268c2391888974c1e50f87bb680
|
||||
SHA512 (v7.12.1.tar.gz) = c1297ebfc659102d73283255cfda4a977dfbff9bdd3748e05de405dadb70f752ad39aa5848edda9143d8ec620d07c21f1551fa4a914c99397620ab1682e58458
|
||||
SHA512 (keylime-selinux-38.1.0.tar.gz) = cbb54511b14a0352e1c2679909b0dcbc00924bacf8f783b230a782d0fae6e3b0168704ea4896c273199163e04a26bcb6217cf30dc480fc300e1fdcb7e39d00a8
|
||||
|
||||
Loading…
Reference in New Issue
Block a user