Files
platform-core/scripts/lib/k3s-local-recovery-a1.sh
T

1143 lines
54 KiB
Bash

#!/usr/bin/env bash
# Source-only strict A1 recovery payload verifier.
readonly K3SLRA1_MANIFEST_MAX_BYTES=65536
readonly K3SLRA1_PATH_MAX_BYTES=512
readonly K3SLRA1_MOUNT_RECORD_MAX_BYTES=4096
readonly K3SLRA1_TARGET_COUNT=80
readonly K3SLRA1_TARGET_BYTES=22857829
readonly K3SLRA1_METADATA_FORMAT='%d:%i|%h|%s|%y|%F|%u:%g|%a'
readonly K3SLRA1_CANONICAL_DATABASE='./datastore/state.db'
readonly K3SLRA1_LEGACY_DATABASE='./rootfs/var/lib/rancher/k3s/server/db/state.db'
readonly K3SLRA1_MAIN_MAPPER='/dev/mapper/k3s-recovery'
readonly K3SLRA1_PROOF_MAPPER='/dev/mapper/k3s-recovery-proof'
readonly K3SLRA1_MAIN_MAPPING_NAME=k3s-recovery
readonly K3SLRA1_PROOF_MAPPING_NAME=k3s-recovery-proof
readonly K3SLRA1_SQLITE_QUERY='PRAGMA query_only=ON; PRAGMA quick_check;'
_k3slra1_command() {
"$@"
}
_k3slra1_output_name_is_safe() {
local output_name="${1-}"
(( $# == 1 )) || return 1
[[ "$output_name" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || return 1
[[ "$output_name" != _k3slra1_* ]]
}
_k3slra1_metadata() {
local path="${1-}" output_name="${2-}" line=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != path ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != line ]] || return 1
_k3slra1_packet_line metadata "$path" line || return 1
printf -v "$output_name" '%s' "$line"
}
_k3slra1_canonical_path() {
local path="${1-}" output_name="${2-}" line=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != path ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != line ]] || return 1
_k3slra1_packet_line readlink "$path" line || return 1
printf -v "$output_name" '%s' "$line"
}
_k3slra1_metadata_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/stat --format="$K3SLRA1_METADATA_FORMAT" -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_fd_metadata_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/stat --dereference --format="$K3SLRA1_METADATA_FORMAT" -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_mapper_stat_packet() {
local mapper="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/stat --format='%F|%Hr:%Lr' -- "$mapper" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_size_stat_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/stat --format='%s' -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_wc_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/wc -c -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_od_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/od -An -v -tx1 -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_sha256_packet() {
local path="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/sha256sum -- "$path" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_findmnt_packet() {
local mount_root="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/findmnt --noheadings --raw --mountpoint "$mount_root" --output SOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS,MAJ:MIN 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_readlink_packet() {
local mapper="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/readlink --canonicalize-existing -- "$mapper" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_lsblk_packet() {
local mapper="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/lsblk --noheadings --nodeps --raw --output MAJ:MIN -- "$mapper" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_blockdev_packet() {
local mapper="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/sbin/blockdev --getro "$mapper" 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf '\0RC=%s\0' "$rc"
}
_k3slra1_stderr_marker() {
local chunk='' read_rc=0
if IFS= read -r -d '' -n 1 chunk; then
read_rc=0
else
read_rc=$?
fi
if (( read_rc == 0 )); then
printf '\0STDERR\0'
while IFS= read -r -d '' -n 4096 chunk; do
:
done
else
if [[ -n "$chunk" ]]; then
printf '\0STDERR\0'
fi
fi
}
_k3slra1_packet_value() {
local producer="${1-}" argument="${2-}" output_name="${3-}"
local -a records=()
(( $# == 3 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != producer ]] || return 1
[[ "$output_name" != argument ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != records ]] || return 1
case "$producer" in
findmnt) mapfile -d '' -t records < <(_k3slra1_findmnt_packet "$argument") ;;
metadata) mapfile -d '' -t records < <(_k3slra1_metadata_packet "$argument") ;;
fd-metadata) mapfile -d '' -t records < <(_k3slra1_fd_metadata_packet "$argument") ;;
mapper-stat) mapfile -d '' -t records < <(_k3slra1_mapper_stat_packet "$argument") ;;
size-stat) mapfile -d '' -t records < <(_k3slra1_size_stat_packet "$argument") ;;
wc) mapfile -d '' -t records < <(_k3slra1_wc_packet "$argument") ;;
od) mapfile -d '' -t records < <(_k3slra1_od_packet "$argument") ;;
sha256) mapfile -d '' -t records < <(_k3slra1_sha256_packet "$argument") ;;
readlink) mapfile -d '' -t records < <(_k3slra1_readlink_packet "$argument") ;;
lsblk) mapfile -d '' -t records < <(_k3slra1_lsblk_packet "$argument") ;;
blockdev) mapfile -d '' -t records < <(_k3slra1_blockdev_packet "$argument") ;;
*) return 1 ;;
esac
(( ${#records[@]} == 2 )) || return 1
[[ "${records[1]}" == RC=0 ]] || return 1
printf -v "$output_name" '%s' "${records[0]}"
}
_k3slra1_packet_line() {
local producer="${1-}" argument="${2-}" output_name="${3-}" value=''
(( $# == 3 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
case "$output_name" in producer|argument|output_name|value) return 1 ;; esac
_k3slra1_packet_value "$producer" "$argument" value || return 1
[[ "$value" == *$'\n' ]] || return 1
[[ "$value" != *$'\r'* ]] || return 1
value="${value%$'\n'}"
[[ -n "$value" ]] || return 1
[[ "$value" != *$'\n'* ]] || return 1
printf -v "$output_name" '%s' "$value"
}
_k3slra1_option_has() {
local options="${1-}" wanted="${2-}" option
local -a option_list=()
(( $# == 2 )) || return 1
IFS=, read -r -a option_list <<<"$options"
for option in "${option_list[@]}"; do
[[ "$option" == "$wanted" ]] && return 0
done
return 1
}
_k3slra1_expected_mapper() {
local role="${1-}" output_name="${2-}" value=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != role ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != value ]] || return 1
case "$role" in
proof) value="$K3SLRA1_PROOF_MAPPER" ;;
original-baseline|original-final) value="$K3SLRA1_MAIN_MAPPER" ;;
*) return 1 ;;
esac
printf -v "$output_name" '%s' "$value"
}
_k3slra1_capture_mount_mapping_evidence() {
local mount_root="${1-}" role="${2-}" output_name="${3-}"
local expected_mapper='' mount_record='' mount_line='' source='' target='' fstype=''
local vfs_options='' fs_options='' mount_major_minor='' extra=''
local source_canonical='' canonical_mapper='' mapper_major_minor='' mapper_readonly='' mapper_stat=''
(( $# == 3 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
case "$output_name" in
mount_root|role|output_name|expected_mapper|mount_record|mount_line|source|target|fstype|vfs_options|fs_options|mount_major_minor|extra|source_canonical|canonical_mapper|mapper_major_minor|mapper_readonly|mapper_stat) return 1 ;;
esac
_k3slra1_expected_mapper "$role" expected_mapper || return 1
_k3slra1_packet_value findmnt "$mount_root" mount_record || return 1
(( ${#mount_record} >= 1 )) || return 1
(( ${#mount_record} <= K3SLRA1_MOUNT_RECORD_MAX_BYTES )) || return 1
[[ "$mount_record" == *$'\n' ]] || return 1
[[ "$mount_record" != *$'\r'* ]] || return 1
mount_line="${mount_record%$'\n'}"
[[ -n "$mount_line" ]] || return 1
[[ "$mount_line" != *$'\n'* ]] || return 1
[[ "$mount_line" =~ ^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)$ ]] || return 1
source="${BASH_REMATCH[1]}"
target="${BASH_REMATCH[2]}"
fstype="${BASH_REMATCH[3]}"
vfs_options="${BASH_REMATCH[4]}"
fs_options="${BASH_REMATCH[5]}"
mount_major_minor="${BASH_REMATCH[6]}"
[[ -n "$source" ]] || return 1
[[ -n "$target" ]] || return 1
[[ -n "$fstype" ]] || return 1
[[ -n "$vfs_options" ]] || return 1
[[ -n "$fs_options" ]] || return 1
[[ -n "$mount_major_minor" ]] || return 1
[[ -z "$extra" ]] || return 1
[[ "$target" == "$mount_root" ]] || return 1
[[ "$fstype" == ext4 ]] || return 1
_k3slra1_option_has "$vfs_options" ro || return 1
_k3slra1_option_has "$vfs_options" nodev || return 1
_k3slra1_option_has "$vfs_options" nosuid || return 1
_k3slra1_option_has "$vfs_options" noexec || return 1
case ",${vfs_options}," in *,rw,*|*,dev,*|*,suid,*|*,exec,*) return 1 ;; esac
_k3slra1_option_has "$fs_options" noload || return 1
_k3slra1_packet_line readlink "$source" source_canonical || return 1
_k3slra1_packet_line readlink "$expected_mapper" canonical_mapper || return 1
[[ "$canonical_mapper" == "$source_canonical" ]] || return 1
[[ "$canonical_mapper" =~ ^/dev/dm-[0-9]+$ ]] || return 1
_k3slra1_packet_line mapper-stat "$canonical_mapper" mapper_stat || return 1
[[ "$mapper_stat" == "block special file|${mount_major_minor}" ]] || return 1
_k3slra1_packet_line lsblk "$canonical_mapper" mapper_major_minor || return 1
[[ "$mapper_major_minor" == "$mount_major_minor" ]] || return 1
_k3slra1_packet_value blockdev "$canonical_mapper" mapper_readonly || return 1
[[ "$mapper_readonly" == $'1\n' ]] || return 1
printf -v "$output_name" '%s' "${mount_record}|${canonical_mapper}|${mapper_major_minor}|${mapper_readonly}"
}
_k3slra1_output_names_are_distinct() {
local name seen_name
local -A seen=()
(( $# >= 1 )) || return 1
for name in "$@"; do
_k3slra1_output_name_is_safe "$name" || return 1
[[ "${seen[$name]+set}" != set ]] || return 1
printf -v 'seen[$name]' '%s' 1
done
}
_k3slra1_output_names_avoid() {
local output_count="${1-}" output_index=0 output_name forbidden_name
local -a output_names=()
(( $# >= 2 )) || return 1
[[ "$output_count" =~ ^[1-9][0-9]*$ ]] || return 1
shift
(( $# >= 10#$output_count + 1 )) || return 1
for (( output_index = 0; output_index < 10#$output_count; output_index += 1 )); do
output_names+=("${1-}")
shift
done
for forbidden_name in "$@"; do
for output_name in "${output_names[@]}"; do
[[ "$output_name" != "$forbidden_name" ]] || return 1
done
done
}
_k3slra1_metadata_fields() {
local path="${1-}" out_identity="${2-}" out_nlink="${3-}" out_size="${4-}"
local out_mtime="${5-}" out_type="${6-}" out_owner="${7-}" out_mode="${8-}"
local metadata='' _k3slra1_type_value=''
(( $# == 8 )) || return 1
_k3slra1_output_names_are_distinct "$out_identity" "$out_nlink" "$out_size" "$out_mtime" "$out_type" "$out_owner" "$out_mode" || return 1
case "$out_identity|$out_nlink|$out_size|$out_mtime|$out_type|$out_owner|$out_mode" in
*'|path|'*|path\|*|*\|path|*'|out_identity|'*|out_identity\|*|*\|out_identity|*'|out_nlink|'*|out_nlink\|*|*\|out_nlink|*'|out_size|'*|out_size\|*|*\|out_size|*'|out_mtime|'*|out_mtime\|*|*\|out_mtime|*'|out_type|'*|out_type\|*|*\|out_type|*'|out_owner|'*|out_owner\|*|*\|out_owner|*'|out_mode|'*|out_mode\|*|*\|out_mode|*'|metadata|'*|metadata\|*|*\|metadata) return 1 ;;
esac
_k3slra1_metadata "$path" metadata || return 1
[[ "$metadata" =~ ^([0-9]+:[0-9]+)\|([0-9]+)\|([0-9]+)\|([^|]+)\|(directory|regular[[:space:]]file|regular[[:space:]]empty[[:space:]]file|symbolic[[:space:]]link)\|([0-9]+:[0-9]+)\|([0-9]+)$ ]] || return 1
_k3slra1_type_value="${BASH_REMATCH[5]}"
if [[ "$_k3slra1_type_value" == 'regular empty file' ]]; then
printf -v _k3slra1_type_value '%s' 'regular file'
fi
printf -v "$out_identity" '%s' "${BASH_REMATCH[1]}"
printf -v "$out_nlink" '%s' "${BASH_REMATCH[2]}"
printf -v "$out_size" '%s' "${BASH_REMATCH[3]}"
printf -v "$out_mtime" '%s' "${BASH_REMATCH[4]}"
printf -v "$out_type" '%s' "$_k3slra1_type_value"
printf -v "$out_owner" '%s' "${BASH_REMATCH[6]}"
printf -v "$out_mode" '%s' "${BASH_REMATCH[7]}"
}
_k3slra1_fd_metadata_fields() {
local path="${1-}" out_identity="${2-}" out_nlink="${3-}" out_size="${4-}"
local out_mtime="${5-}" out_type="${6-}" out_owner="${7-}" out_mode="${8-}"
local metadata='' _k3slra1_type_value=''
(( $# == 8 )) || return 1
_k3slra1_output_names_are_distinct "$out_identity" "$out_nlink" "$out_size" "$out_mtime" "$out_type" "$out_owner" "$out_mode" || return 1
case "$out_identity|$out_nlink|$out_size|$out_mtime|$out_type|$out_owner|$out_mode" in
*'|path|'*|path\|*|*\|path|*'|out_identity|'*|out_identity\|*|*\|out_identity|*'|out_nlink|'*|out_nlink\|*|*\|out_nlink|*'|out_size|'*|out_size\|*|*\|out_size|*'|out_mtime|'*|out_mtime\|*|*\|out_mtime|*'|out_type|'*|out_type\|*|*\|out_type|*'|out_owner|'*|out_owner\|*|*\|out_owner|*'|out_mode|'*|out_mode\|*|*\|out_mode|*'|metadata|'*|metadata\|*|*\|metadata) return 1 ;;
esac
_k3slra1_packet_line fd-metadata "$path" metadata || return 1
[[ "$metadata" =~ ^([0-9]+:[0-9]+)\|([0-9]+)\|([0-9]+)\|([^|]+)\|(directory|regular[[:space:]]file|regular[[:space:]]empty[[:space:]]file|symbolic[[:space:]]link)\|([0-9]+:[0-9]+)\|([0-9]+)$ ]] || return 1
_k3slra1_type_value="${BASH_REMATCH[5]}"
if [[ "$_k3slra1_type_value" == 'regular empty file' ]]; then
printf -v _k3slra1_type_value '%s' 'regular file'
fi
printf -v "$out_identity" '%s' "${BASH_REMATCH[1]}"
printf -v "$out_nlink" '%s' "${BASH_REMATCH[2]}"
printf -v "$out_size" '%s' "${BASH_REMATCH[3]}"
printf -v "$out_mtime" '%s' "${BASH_REMATCH[4]}"
printf -v "$out_type" '%s' "$_k3slra1_type_value"
printf -v "$out_owner" '%s' "${BASH_REMATCH[6]}"
printf -v "$out_mode" '%s' "${BASH_REMATCH[7]}"
}
_k3slra1_find_mount_children_packet() {
local mount_root="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/find "$mount_root" -mindepth 1 -maxdepth 1 -print0 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf 'RC=%s\0' "$rc"
}
_k3slra1_find_regular_packet() {
local pre_root="${1-}" rc=0
(( $# == 1 )) || return 1
if _k3slra1_command /usr/bin/find "$pre_root" -xdev -type f -print0 2> >(_k3slra1_stderr_marker); then
rc=0
else
rc=$?
fi
printf 'RC=%s\0' "$rc"
}
_k3slra1_select_pre_bundle() {
local mount_root="${1-}" output_name="${2-}" entry base _k3slra1_selected_value=''
local canonical_mount='' canonical_bundle='' canonical_pre='' canonical_manifest=''
local mount_identity='' mount_nlink='' mount_size='' mount_mtime='' mount_type='' mount_owner='' mount_mode=''
local bundle_identity='' bundle_nlink='' bundle_size='' bundle_mtime='' bundle_type='' bundle_owner='' bundle_mode=''
local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode=''
local manifest_identity='' manifest_nlink='' manifest_size='' manifest_mtime='' manifest_type='' manifest_owner='' manifest_mode=''
local pre_root='' manifest='' match_count=0 last_index=0
local -a entries=()
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
_k3slra1_output_names_avoid 1 "$output_name" mount_root output_name entry base canonical_mount canonical_bundle canonical_pre canonical_manifest mount_identity mount_nlink mount_size mount_mtime mount_type mount_owner mount_mode bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode manifest_identity manifest_nlink manifest_size manifest_mtime manifest_type manifest_owner manifest_mode pre_root manifest match_count last_index entries || return 1
mapfile -d '' -t entries < <(_k3slra1_find_mount_children_packet "$mount_root")
(( ${#entries[@]} >= 1 )) || return 1
(( last_index = ${#entries[@]} - 1 ))
[[ "${entries[$last_index]}" == RC=0 ]] || return 1
unset 'entries[last_index]'
for entry in "${entries[@]}"; do
[[ -n "$entry" ]] || return 1
[[ "$entry" != STDERR ]] || return 1
base="${entry##*/}"
if [[ "$base" =~ ^k3s-secrets-encryption-[0-9]{8}T[0-9]{6}Z$ ]]; then
(( match_count += 1 ))
_k3slra1_selected_value="$entry"
fi
done
(( match_count == 1 )) || return 1
pre_root="${_k3slra1_selected_value}/pre"
manifest="${pre_root}/verification.manifest"
_k3slra1_canonical_path "$mount_root" canonical_mount || return 1
_k3slra1_canonical_path "$_k3slra1_selected_value" canonical_bundle || return 1
_k3slra1_canonical_path "$pre_root" canonical_pre || return 1
_k3slra1_canonical_path "$manifest" canonical_manifest || return 1
[[ "$canonical_mount" == "$mount_root" ]] || return 1
[[ "$canonical_bundle" == "$_k3slra1_selected_value" ]] || return 1
[[ "$canonical_pre" == "$pre_root" ]] || return 1
[[ "$canonical_manifest" == "$manifest" ]] || return 1
_k3slra1_metadata_fields "$mount_root" mount_identity mount_nlink mount_size mount_mtime mount_type mount_owner mount_mode || return 1
_k3slra1_metadata_fields "$_k3slra1_selected_value" bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode || return 1
_k3slra1_metadata_fields "$pre_root" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1
_k3slra1_metadata_fields "$manifest" manifest_identity manifest_nlink manifest_size manifest_mtime manifest_type manifest_owner manifest_mode || return 1
[[ "$mount_type" == directory ]] || return 1
[[ "$bundle_type" == directory ]] || return 1
[[ "$pre_type" == directory ]] || return 1
[[ "$manifest_type" == 'regular file' ]] || return 1
[[ "$bundle_owner" == 0:0 ]] || return 1
[[ "$pre_owner" == 0:0 ]] || return 1
[[ "$manifest_owner" == 0:0 ]] || return 1
[[ "$bundle_mode" == 700 ]] || return 1
[[ "$pre_mode" == 700 ]] || return 1
[[ "$manifest_mode" == 600 ]] || return 1
[[ "$manifest_nlink" == 1 ]] || return 1
[[ "${bundle_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1
[[ "${pre_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1
[[ "${manifest_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1
printf -v "$output_name" '%s' "$_k3slra1_selected_value"
}
_k3slra1_capture_manifest_hex() {
local manifest="${1-}" output_name="${2-}" stat_size='' byte_count='' od_output='' hex=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != manifest ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != size ]] || return 1
[[ "$output_name" != stat_size ]] || return 1
[[ "$output_name" != byte_count ]] || return 1
[[ "$output_name" != od_output ]] || return 1
[[ "$output_name" != hex ]] || return 1
_k3slra1_packet_line size-stat "$manifest" stat_size || return 1
[[ "$stat_size" =~ ^[0-9]+$ ]] || return 1
(( 10#$stat_size >= 1 )) || return 1
(( 10#$stat_size <= K3SLRA1_MANIFEST_MAX_BYTES )) || return 1
_k3slra1_packet_line wc "$manifest" byte_count || return 1
[[ "$byte_count" == *"$manifest" ]] || return 1
byte_count="${byte_count%"$manifest"}"
[[ "$byte_count" == *[[:space:]] ]] || return 1
byte_count="${byte_count//[[:space:]]/}"
[[ "$byte_count" == "$stat_size" ]] || return 1
_k3slra1_packet_value od "$manifest" od_output || return 1
[[ "$od_output" == *$'\n' ]] || return 1
[[ "$od_output" != *$'\r'* ]] || return 1
od_output="${od_output%$'\n'}"
[[ -n "$od_output" ]] || return 1
[[ "$od_output" != *$'\n' ]] || return 1
[[ "$od_output" != *$'\n\n'* ]] || return 1
hex="${od_output//[[:space:]]/}"
[[ "$hex" =~ ^[0-9a-f]+$ ]] || return 1
(( ${#hex} == 10#$stat_size * 2 )) || return 1
[[ " $od_output " != *[[:space:]]00[[:space:]]* ]] || return 1
[[ " $od_output " != *[[:space:]]0d[[:space:]]* ]] || return 1
[[ "${hex: -2}" == 0a ]] || return 1
printf -v "$output_name" '%s' "$hex"
}
_k3slra1_verify_payload() {
# Internal-only: the proof orchestrator supplies a reviewed helper staged in
# its root-owned runtime tmpfs before this privileged dispatch boundary.
local mount_root="${1-}" role="${2-}" capture_root="${3-}"
local helper=''
(( $# == 3 )) || return 1
case "$role" in
original-baseline|proof|original-final) ;;
*) return 1 ;;
esac
helper="${capture_root}/libexec/k3s-local-recovery-a1-check.sh"
_k3slra1_command /usr/bin/sudo --non-interactive -- /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LC_ALL=C /usr/bin/bash --noprofile --norc -- "$helper" "$mount_root" "$role" "$capture_root" >/dev/null 2>&1
}
_k3slra1_verify_payload_root() {
local mount_root="${1-}" role="${2-}" capture_root="${3-}"
local _bundle='' _layout='' _count_before='' _bytes_before='' _snapshot_before=''
local _count_after='' _bytes_after='' _snapshot_after=''
local _mount_before='' _mount_sqlite='' _mount_after='' _sqlite_rc=0
(( $# == 3 )) || return 1
case "$role" in
original-baseline|proof|original-final) ;;
*) return 1 ;;
esac
_k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_before || return 1
_k3slra1_select_pre_bundle "$mount_root" _bundle || return 1
_k3slra1_analyze_manifest "$_bundle" _count_before _bytes_before _snapshot_before || return 1
[[ "$_count_before" == "$K3SLRA1_TARGET_COUNT" ]] || return 1
[[ "$_bytes_before" == "$K3SLRA1_TARGET_BYTES" ]] || return 1
_k3slra1_select_sqlite_layout_from_snapshot "$_bundle" "$_snapshot_before" _layout || return 1
_k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_sqlite || return 1
[[ "$_mount_sqlite" == "$_mount_before" ]] || return 1
if _k3slra1_sqlite_quick_check "$_bundle" "$_layout" "$capture_root"; then
_sqlite_rc=0
else
_sqlite_rc=$?
fi
case "$_sqlite_rc" in
0) ;;
130|143) return "$_sqlite_rc" ;;
*) return 1 ;;
esac
_k3slra1_analyze_manifest "$_bundle" _count_after _bytes_after _snapshot_after || return 1
[[ "$_count_after" == "$_count_before" ]] || return 1
[[ "$_bytes_after" == "$_bytes_before" ]] || return 1
[[ "$_snapshot_after" == "$_snapshot_before" ]] || return 1
_k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_after || return 1
[[ "$_mount_after" == "$_mount_before" ]]
}
_k3slra1_sha256_record() {
local path="${1-}" output_name="${2-}" line=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != path ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != value ]] || return 1
[[ "$output_name" != line ]] || return 1
_k3slra1_packet_line sha256 "$path" line || return 1
printf -v "$output_name" '%s' "$line"
}
_k3slra1_analyze_manifest() {
local bundle="${1-}" out_count="${2-}" out_bytes="${3-}" out_snapshot="${4-}"
local mount_root='' _selected_value='' pre_root='' manifest='' manifest_hex_before='' manifest_hex_after=''
local bundle_identity='' bundle_nlink='' bundle_size='' bundle_mtime='' bundle_type='' bundle_owner='' bundle_mode=''
local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode=''
local manifest_identity_before='' manifest_nlink_before='' manifest_size_before='' manifest_mtime_before=''
local manifest_type_before='' manifest_owner_before='' manifest_mode_before='' manifest_record_before=''
local manifest_identity_after='' manifest_nlink_after='' manifest_size_after='' manifest_mtime_after=''
local manifest_type_after='' manifest_owner_after='' manifest_mode_after='' manifest_record_after=''
local line='' hash='' relative='' target='' canonical_target='' target_record_before='' target_record_after=''
local target_identity='' target_nlink='' target_size='' target_mtime='' target_type='' target_owner='' target_mode=''
local inventory_path='' _snapshot_value='' _count_value=0 _bytes_value=0
local last_index=0 inventory_count=0
local -a inventory=() manifest_lines=()
local -A seen_paths=() seen_inodes=() expected_inventory=() seen_inventory=()
(( $# == 4 )) || return 1
_k3slra1_output_names_are_distinct "$out_count" "$out_bytes" "$out_snapshot" || return 1
_k3slra1_output_names_avoid 3 "$out_count" "$out_bytes" "$out_snapshot" bundle out_count out_bytes out_snapshot mount_root _selected_value pre_root manifest manifest_hex_before manifest_hex_after bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode manifest_identity_before manifest_nlink_before manifest_size_before manifest_mtime_before manifest_type_before manifest_owner_before manifest_mode_before manifest_record_before manifest_identity_after manifest_nlink_after manifest_size_after manifest_mtime_after manifest_type_after manifest_owner_after manifest_mode_after manifest_record_after line hash relative target canonical_target target_record_before target_record_after target_identity target_nlink target_size target_mtime target_type target_owner target_mode inventory_path _snapshot_value _count_value _bytes_value last_index inventory_count inventory manifest_lines seen_paths seen_inodes expected_inventory seen_inventory || return 1
mount_root="${bundle%/*}"
[[ -n "$mount_root" ]] || return 1
_k3slra1_select_pre_bundle "$mount_root" _selected_value || return 1
[[ "$_selected_value" == "$bundle" ]] || return 1
pre_root="${bundle}/pre"
manifest="${pre_root}/verification.manifest"
_k3slra1_metadata_fields "$bundle" bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode || return 1
_k3slra1_metadata_fields "$pre_root" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1
_k3slra1_metadata_fields "$manifest" manifest_identity_before manifest_nlink_before manifest_size_before manifest_mtime_before manifest_type_before manifest_owner_before manifest_mode_before || return 1
_k3slra1_capture_manifest_hex "$manifest" manifest_hex_before || return 1
_k3slra1_sha256_record "$manifest" manifest_record_before || return 1
printf -v "expected_inventory[$manifest]" '%s' 1
mapfile -t manifest_lines <"$manifest"
for line in "${manifest_lines[@]}"; do
(( _count_value += 1 ))
(( _count_value <= K3SLRA1_TARGET_COUNT )) || return 1
[[ "$line" =~ ^[0-9a-f]{64}\ \ \./[A-Za-z0-9._+/-]+$ ]] || return 1
hash="${line:0:64}"
relative="${line:66}"
(( ${#relative} <= K3SLRA1_PATH_MAX_BYTES )) || return 1
[[ "$relative" != './verification.manifest' ]] || return 1
[[ "$relative" != *//* ]] || return 1
[[ "$relative" != *'/./'* ]] || return 1
[[ "$relative" != *'/../'* ]] || return 1
[[ "$relative" != */. ]] || return 1
[[ "$relative" != */.. ]] || return 1
[[ "$relative" != */ ]] || return 1
[[ "${seen_paths[$relative]+set}" != set ]] || return 1
printf -v "seen_paths[$relative]" '%s' 1
target="${pre_root}/${relative#./}"
_k3slra1_canonical_path "$target" canonical_target || return 1
[[ "$canonical_target" == "$target" ]] || return 1
_k3slra1_metadata_fields "$target" target_identity target_nlink target_size target_mtime target_type target_owner target_mode || return 1
[[ "$target_type" == 'regular file' ]] || return 1
[[ "$target_nlink" == 1 ]] || return 1
[[ "${target_identity%%:*}" == "${pre_identity%%:*}" ]] || return 1
[[ "${seen_inodes[$target_identity]+set}" != set ]] || return 1
printf -v "seen_inodes[$target_identity]" '%s' 1
target_record_before="${target_identity}|${target_nlink}|${target_size}|${target_mtime}|${target_type}|${target_owner}|${target_mode}"
_k3slra1_sha256_record "$target" target_record_after || return 1
[[ "$target_record_after" == "${hash} ${target}" ]] || return 1
_k3slra1_metadata_fields "$target" target_identity target_nlink target_size target_mtime target_type target_owner target_mode || return 1
[[ "${target_identity}|${target_nlink}|${target_size}|${target_mtime}|${target_type}|${target_owner}|${target_mode}" == "$target_record_before" ]] || return 1
(( _bytes_value += 10#$target_size ))
printf -v _snapshot_value '%s%s|%s|%s\n' "$_snapshot_value" "$relative" "$target_record_before" "$hash"
printf -v "expected_inventory[$target]" '%s' 1
done
(( _count_value == K3SLRA1_TARGET_COUNT )) || return 1
(( _bytes_value == K3SLRA1_TARGET_BYTES )) || return 1
mapfile -d '' -t inventory < <(_k3slra1_find_regular_packet "$pre_root")
(( ${#inventory[@]} >= 1 )) || return 1
(( last_index = ${#inventory[@]} - 1 ))
[[ "${inventory[$last_index]}" == RC=0 ]] || return 1
unset 'inventory[last_index]'
for inventory_path in "${inventory[@]}"; do
[[ -n "$inventory_path" ]] || return 1
[[ "$inventory_path" != STDERR ]] || return 1
[[ "${expected_inventory[$inventory_path]+set}" == set ]] || return 1
[[ "${seen_inventory[$inventory_path]+set}" != set ]] || return 1
printf -v "seen_inventory[$inventory_path]" '%s' 1
(( inventory_count += 1 ))
done
(( inventory_count == K3SLRA1_TARGET_COUNT + 1 )) || return 1
_k3slra1_metadata_fields "$manifest" manifest_identity_after manifest_nlink_after manifest_size_after manifest_mtime_after manifest_type_after manifest_owner_after manifest_mode_after || return 1
_k3slra1_capture_manifest_hex "$manifest" manifest_hex_after || return 1
_k3slra1_sha256_record "$manifest" manifest_record_after || return 1
[[ "$manifest_identity_after" == "$manifest_identity_before" ]] || return 1
[[ "$manifest_nlink_after" == "$manifest_nlink_before" ]] || return 1
[[ "$manifest_size_after" == "$manifest_size_before" ]] || return 1
[[ "$manifest_mtime_after" == "$manifest_mtime_before" ]] || return 1
[[ "$manifest_type_after" == "$manifest_type_before" ]] || return 1
[[ "$manifest_owner_after" == "$manifest_owner_before" ]] || return 1
[[ "$manifest_mode_after" == "$manifest_mode_before" ]] || return 1
[[ "$manifest_hex_after" == "$manifest_hex_before" ]] || return 1
[[ "$manifest_record_after" == "$manifest_record_before" ]] || return 1
printf -v _snapshot_value '%s%s\n%s\n%s\n' "$_snapshot_value" "$bundle_identity|$bundle_nlink|$bundle_size|$bundle_mtime|$bundle_type|$bundle_owner|$bundle_mode" "$pre_identity|$pre_nlink|$pre_size|$pre_mtime|$pre_type|$pre_owner|$pre_mode" "$manifest_identity_before|$manifest_nlink_before|$manifest_size_before|$manifest_mtime_before|$manifest_type_before|$manifest_owner_before|$manifest_mode_before|$manifest_record_before"
printf -v "$out_count" '%s' "$_count_value"
printf -v "$out_bytes" '%s' "$_bytes_value"
printf -v "$out_snapshot" '%s' "$_snapshot_value"
}
_k3slra1_verify_manifest() {
local bundle="${1-}" out_count="${2-}" out_bytes="${3-}"
local _count_result='' _bytes_result='' _snapshot_result=''
(( $# == 3 )) || return 1
_k3slra1_output_names_are_distinct "$out_count" "$out_bytes" || return 1
_k3slra1_output_names_avoid 2 "$out_count" "$out_bytes" bundle out_count out_bytes _count_result _bytes_result _snapshot_result || return 1
_k3slra1_analyze_manifest "$bundle" _count_result _bytes_result _snapshot_result || return 1
printf -v "$out_count" '%s' "$_count_result"
printf -v "$out_bytes" '%s' "$_bytes_result"
}
_k3slra1_snapshot_metadata_for_relative() {
local snapshot="${1-}" relative="${2-}" output_name="${3-}"
local line='' value='' match_count=0
local -a snapshot_lines=()
(( $# == 3 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
_k3slra1_output_names_avoid 1 "$output_name" snapshot relative output_name line value match_count snapshot_lines || return 1
[[ "$relative" == ./* ]] || return 1
mapfile -t snapshot_lines <<<"$snapshot"
for line in "${snapshot_lines[@]}"; do
if [[ "$line" == "${relative}|"* ]]; then
(( match_count += 1 ))
value="${line#"${relative}|"}"
[[ "$value" =~ \|([0-9a-f]{64})$ ]] || return 1
value="${value%|${BASH_REMATCH[1]}}"
fi
done
(( match_count == 1 )) || return 1
[[ "$value" =~ ^[0-9]+:[0-9]+\|1\|[0-9]+\|.+\|regular[[:space:]]file\|[0-9]+:[0-9]+\|[0-9]+$ ]] || return 1
printf -v "$output_name" '%s' "$value"
}
_k3slra1_sqlite_selected_path_matches() {
local path="${1-}" expected_device="${2-}" expected_record="${3-}" canonical=''
local identity='' nlink='' size='' mtime='' type='' owner='' mode='' current_record=''
(( $# == 3 )) || return 1
_k3slra1_canonical_path "$path" canonical || return 1
[[ "$canonical" == "$path" ]] || return 1
_k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1
[[ "${identity%%:*}" == "$expected_device" ]] || return 1
[[ "$nlink" == 1 ]] || return 1
[[ "$type" == 'regular file' ]] || return 1
current_record="${identity}|${nlink}|${size}|${mtime}|${type}|${owner}|${mode}"
[[ "$current_record" == "$expected_record" ]]
}
_k3slra1_select_sqlite_layout_from_snapshot() {
local bundle="${1-}" snapshot="${2-}" output_name="${3-}" path relative=''
local expected_record='' canonical_count=0 legacy_count=0 _k3slra1_layout_value=''
local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode='' pre_device=''
local -a selected_paths=() canonical_paths=("${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}" "${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}-wal" "${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}-shm") legacy_paths=("${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}" "${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}-wal" "${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}-shm")
(( $# == 3 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
_k3slra1_output_names_avoid 1 "$output_name" bundle snapshot output_name path relative expected_record canonical_count legacy_count pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode pre_device selected_paths canonical_paths legacy_paths || return 1
_k3slra1_metadata_fields "${bundle}/pre" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1
pre_device="${pre_identity%%:*}"
for path in "${canonical_paths[@]}"; do
if [[ -e "$path" ]]; then
(( canonical_count += 1 ))
else
if [[ -L "$path" ]]; then
(( canonical_count += 1 ))
fi
fi
done
for path in "${legacy_paths[@]}"; do
if [[ -e "$path" ]]; then
(( legacy_count += 1 ))
else
if [[ -L "$path" ]]; then
(( legacy_count += 1 ))
fi
fi
done
if (( canonical_count == 3 )); then
(( legacy_count == 0 )) || return 1
_k3slra1_layout_value=canonical
selected_paths=("${canonical_paths[@]}")
else
if (( legacy_count == 3 )); then
(( canonical_count == 0 )) || return 1
_k3slra1_layout_value=legacy
selected_paths=("${legacy_paths[@]}")
else
return 1
fi
fi
for path in "${selected_paths[@]}"; do
relative="./${path#"${bundle}/pre/"}"
_k3slra1_snapshot_metadata_for_relative "$snapshot" "$relative" expected_record || return 1
_k3slra1_sqlite_selected_path_matches "$path" "$pre_device" "$expected_record" || return 1
done
printf -v "$output_name" '%s' "$_k3slra1_layout_value"
}
_k3slra1_select_sqlite_layout() {
local bundle="${1-}" output_name="${2-}" count='' bytes='' snapshot=''
(( $# == 2 )) || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
_k3slra1_output_names_avoid 1 "$output_name" bundle output_name count bytes snapshot path || return 1
_k3slra1_analyze_manifest "$bundle" count bytes snapshot || return 1
_k3slra1_select_sqlite_layout_from_snapshot "$bundle" "$snapshot" "$output_name"
}
_k3slra1_capture_file_hex() {
local file="${1-}" maximum="${2-}" output_name="${3-}" size='' count='' od_output='' hex=''
(( $# == 3 )) || return 1
[[ "$maximum" =~ ^[1-9][0-9]*$ ]] || return 1
_k3slra1_output_name_is_safe "$output_name" || return 1
[[ "$output_name" != file ]] || return 1
[[ "$output_name" != maximum ]] || return 1
[[ "$output_name" != output_name ]] || return 1
[[ "$output_name" != size ]] || return 1
[[ "$output_name" != count ]] || return 1
[[ "$output_name" != od_output ]] || return 1
[[ "$output_name" != hex ]] || return 1
_k3slra1_packet_line size-stat "$file" size || return 1
[[ "$size" =~ ^[0-9]+$ ]] || return 1
(( 10#$size <= 10#$maximum )) || return 1
_k3slra1_packet_line wc "$file" count || return 1
[[ "$count" == *"$file" ]] || return 1
count="${count%"$file"}"
[[ "$count" == *[[:space:]] ]] || return 1
count="${count//[[:space:]]/}"
[[ "$count" == "$size" ]] || return 1
_k3slra1_packet_value od "$file" od_output || return 1
[[ "$od_output" != *$'\r'* ]] || return 1
if [[ -n "$od_output" ]]; then
[[ "$od_output" == *$'\n' ]] || return 1
od_output="${od_output%$'\n'}"
[[ -n "$od_output" ]] || return 1
[[ "$od_output" != *$'\n' ]] || return 1
[[ "$od_output" != *$'\n\n'* ]] || return 1
fi
hex="${od_output//[[:space:]]/}"
if (( 10#$size == 0 )); then
[[ -z "$hex" ]] || return 1
else
[[ "$hex" =~ ^[0-9a-f]+$ ]] || return 1
(( ${#hex} == 10#$size * 2 )) || return 1
fi
printf -v "$output_name" '%s' "$hex"
}
_k3slra1_sqlite_capture_transaction() {
local database="${1-}" capture_root="${2-}" stdout_path="${3-}" stderr_path="${4-}"
local parent_identity_before='' parent_nlink='' parent_size='' parent_mtime='' parent_type='' parent_owner='' parent_mode=''
local parent_fd_identity_after='' parent_fd_nlink_after='' parent_fd_size_after=''
local parent_fd_mtime_after='' parent_fd_type_after='' parent_fd_owner_after='' parent_fd_mode_after=''
local stdout_identity_before='' stdout_nlink='' stdout_size='' stdout_mtime='' stdout_type='' stdout_owner='' stdout_mode=''
local stdout_fd_identity_after='' stdout_fd_nlink_after='' stdout_fd_size_after=''
local stdout_fd_mtime_after='' stdout_fd_type_after='' stdout_fd_owner_after='' stdout_fd_mode_after=''
local stderr_identity_before='' stderr_nlink='' stderr_size='' stderr_mtime='' stderr_type='' stderr_owner='' stderr_mode=''
local stderr_fd_identity='' stderr_fd_nlink='' stderr_fd_size='' stderr_fd_mtime='' stderr_fd_type='' stderr_fd_owner='' stderr_fd_mode=''
local stderr_fd_identity_after='' stderr_fd_nlink_after='' stderr_fd_size_after=''
local stderr_fd_mtime_after='' stderr_fd_type_after='' stderr_fd_owner_after='' stderr_fd_mode_after=''
local parent_identity_after='' parent_nlink_after='' parent_size_after='' parent_mtime_after='' parent_type_after='' parent_owner_after='' parent_mode_after=''
local stdout_identity_after='' stdout_nlink_after='' stdout_size_after='' stdout_mtime_after='' stdout_type_after='' stdout_owner_after='' stdout_mode_after=''
local stderr_identity_after='' stderr_nlink_after='' stderr_size_after='' stderr_mtime_after='' stderr_type_after='' stderr_owner_after='' stderr_mode_after=''
local stdout_hex='' stderr_hex='' validation_rc=0 child_rc=1 cleanup_rc=0
(( $# == 4 )) || return 1
_capture_entered=1
if _k3slra1_metadata_fields "$capture_root" parent_identity_before parent_nlink parent_size parent_mtime parent_type parent_owner parent_mode; then
:
else
validation_rc=1
fi
if _k3slra1_metadata_fields "$stdout_path" stdout_identity_before stdout_nlink stdout_size stdout_mtime stdout_type stdout_owner stdout_mode; then
:
else
validation_rc=1
fi
if _k3slra1_metadata_fields "$stderr_path" stderr_identity_before stderr_nlink stderr_size stderr_mtime stderr_type stderr_owner stderr_mode; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/8" stderr_fd_identity stderr_fd_nlink stderr_fd_size stderr_fd_mtime stderr_fd_type stderr_fd_owner stderr_fd_mode; then
:
else
validation_rc=1
fi
[[ "$parent_type" == directory ]] || validation_rc=1
[[ "$parent_owner" == 0:0 ]] || validation_rc=1
[[ "$parent_mode" == 700 ]] || validation_rc=1
[[ "$_stage_parent_fd_type" == directory ]] || validation_rc=1
[[ "$_stage_parent_fd_owner" == 0:0 ]] || validation_rc=1
[[ "$_stage_parent_fd_mode" == 700 ]] || validation_rc=1
[[ "$_stage_parent_identity" == "$parent_identity_before" ]] || validation_rc=1
[[ "$_stage_parent_fd_identity" == "$parent_identity_before" ]] || validation_rc=1
[[ "$stdout_type" == 'regular file' ]] || validation_rc=1
[[ "$stderr_type" == 'regular file' ]] || validation_rc=1
[[ "$stdout_owner" == 0:0 ]] || validation_rc=1
[[ "$stderr_owner" == 0:0 ]] || validation_rc=1
[[ "$stdout_mode" == 600 ]] || validation_rc=1
[[ "$stderr_mode" == 600 ]] || validation_rc=1
[[ "$stdout_nlink" == 1 ]] || validation_rc=1
[[ "$stderr_nlink" == 1 ]] || validation_rc=1
[[ "$_stage_stdout_fd_type" == 'regular file' ]] || validation_rc=1
[[ "$stderr_fd_type" == 'regular file' ]] || validation_rc=1
[[ "$_stage_stdout_fd_owner" == 0:0 ]] || validation_rc=1
[[ "$stderr_fd_owner" == 0:0 ]] || validation_rc=1
[[ "$_stage_stdout_fd_mode" == 600 ]] || validation_rc=1
[[ "$stderr_fd_mode" == 600 ]] || validation_rc=1
[[ "$_stage_stdout_fd_nlink" == 1 ]] || validation_rc=1
[[ "$stderr_fd_nlink" == 1 ]] || validation_rc=1
[[ "$stdout_identity_before" == "$_stage_stdout_identity" ]] || validation_rc=1
[[ "$stdout_identity_before" == "$_stage_stdout_fd_identity" ]] || validation_rc=1
[[ "$stderr_identity_before" == "$stderr_fd_identity" ]] || validation_rc=1
[[ "$stdout_size" == "$_stage_stdout_fd_size" ]] || validation_rc=1
[[ "$stderr_size" == "$stderr_fd_size" ]] || validation_rc=1
[[ "$stdout_mtime" == "$_stage_stdout_fd_mtime" ]] || validation_rc=1
[[ "$stderr_mtime" == "$stderr_fd_mtime" ]] || validation_rc=1
[[ "$stdout_type" == "$_stage_stdout_fd_type" ]] || validation_rc=1
[[ "$stderr_type" == "$stderr_fd_type" ]] || validation_rc=1
[[ "$stdout_owner" == "$_stage_stdout_fd_owner" ]] || validation_rc=1
[[ "$stderr_owner" == "$stderr_fd_owner" ]] || validation_rc=1
[[ "$stdout_mode" == "$_stage_stdout_fd_mode" ]] || validation_rc=1
[[ "$stderr_mode" == "$stderr_fd_mode" ]] || validation_rc=1
[[ "$stderr_size" == 0 ]] || validation_rc=1
[[ "$stdout_identity_before" != "$stderr_identity_before" ]] || validation_rc=1
if (( validation_rc == 0 )); then
if _k3slra1_command /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LC_ALL=C "HOME=${capture_root}/home" /usr/bin/sqlite3 -safe -nofollow -readonly -batch -bail -noheader -init /dev/null "$database" "$K3SLRA1_SQLITE_QUERY" >&7 2>&8; then
child_rc=0
else
child_rc=$?
fi
fi
if _k3slra1_metadata_fields "$stdout_path" stdout_identity_after stdout_nlink_after stdout_size_after stdout_mtime_after stdout_type_after stdout_owner_after stdout_mode_after; then
:
else
validation_rc=1
fi
if _k3slra1_metadata_fields "$stderr_path" stderr_identity_after stderr_nlink_after stderr_size_after stderr_mtime_after stderr_type_after stderr_owner_after stderr_mode_after; then
:
else
validation_rc=1
fi
if _k3slra1_metadata_fields "$capture_root" parent_identity_after parent_nlink_after parent_size_after parent_mtime_after parent_type_after parent_owner_after parent_mode_after; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/6" parent_fd_identity_after parent_fd_nlink_after parent_fd_size_after parent_fd_mtime_after parent_fd_type_after parent_fd_owner_after parent_fd_mode_after; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/7" stdout_fd_identity_after stdout_fd_nlink_after stdout_fd_size_after stdout_fd_mtime_after stdout_fd_type_after stdout_fd_owner_after stdout_fd_mode_after; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/8" stderr_fd_identity_after stderr_fd_nlink_after stderr_fd_size_after stderr_fd_mtime_after stderr_fd_type_after stderr_fd_owner_after stderr_fd_mode_after; then
:
else
validation_rc=1
fi
[[ "$parent_identity_after" == "$parent_identity_before" ]] || validation_rc=1
[[ "$parent_identity_after" == "$parent_fd_identity_after" ]] || validation_rc=1
[[ "$parent_fd_identity_after" == "$_stage_parent_fd_identity" ]] || validation_rc=1
[[ "$parent_type_after" == directory ]] || validation_rc=1
[[ "$parent_fd_type_after" == directory ]] || validation_rc=1
[[ "$parent_owner_after" == 0:0 ]] || validation_rc=1
[[ "$parent_fd_owner_after" == 0:0 ]] || validation_rc=1
[[ "$parent_mode_after" == 700 ]] || validation_rc=1
[[ "$parent_fd_mode_after" == 700 ]] || validation_rc=1
[[ "$stdout_identity_after" == "$stdout_identity_before" ]] || validation_rc=1
[[ "$stdout_identity_after" == "$stdout_fd_identity_after" ]] || validation_rc=1
[[ "$stdout_nlink_after" == 1 ]] || validation_rc=1
[[ "$stdout_fd_nlink_after" == 1 ]] || validation_rc=1
[[ "$stdout_type_after" == 'regular file' ]] || validation_rc=1
[[ "$stdout_fd_type_after" == 'regular file' ]] || validation_rc=1
[[ "$stdout_owner_after" == 0:0 ]] || validation_rc=1
[[ "$stdout_fd_owner_after" == 0:0 ]] || validation_rc=1
[[ "$stdout_mode_after" == 600 ]] || validation_rc=1
[[ "$stdout_fd_mode_after" == 600 ]] || validation_rc=1
[[ "$stdout_size_after" == "$stdout_fd_size_after" ]] || validation_rc=1
[[ "$stdout_mtime_after" == "$stdout_fd_mtime_after" ]] || validation_rc=1
[[ "$stderr_identity_after" == "$stderr_identity_before" ]] || validation_rc=1
[[ "$stderr_identity_after" == "$stderr_fd_identity_after" ]] || validation_rc=1
[[ "$stderr_nlink_after" == 1 ]] || validation_rc=1
[[ "$stderr_fd_nlink_after" == 1 ]] || validation_rc=1
[[ "$stderr_type_after" == 'regular file' ]] || validation_rc=1
[[ "$stderr_fd_type_after" == 'regular file' ]] || validation_rc=1
[[ "$stderr_owner_after" == 0:0 ]] || validation_rc=1
[[ "$stderr_fd_owner_after" == 0:0 ]] || validation_rc=1
[[ "$stderr_mode_after" == 600 ]] || validation_rc=1
[[ "$stderr_fd_mode_after" == 600 ]] || validation_rc=1
[[ "$stderr_size_after" == "$stderr_fd_size_after" ]] || validation_rc=1
[[ "$stderr_mtime_after" == "$stderr_fd_mtime_after" ]] || validation_rc=1
if (( validation_rc == 0 )); then
_k3slra1_capture_file_hex "$stdout_path" 16 stdout_hex || validation_rc=1
_k3slra1_capture_file_hex "$stderr_path" 16 stderr_hex || validation_rc=1
[[ "$stdout_hex" == 6f6b0a ]] || validation_rc=1
[[ -z "$stderr_hex" ]] || validation_rc=1
(( child_rc == 0 )) || validation_rc=1
fi
_k3slra1_remove_owned_capture "$stdout_path" "$stdout_identity_before" || cleanup_rc=1
_k3slra1_remove_owned_capture "$stderr_path" "$stderr_identity_before" || cleanup_rc=1
if _k3slra1_metadata_fields "$capture_root" parent_identity_after parent_nlink_after parent_size_after parent_mtime_after parent_type_after parent_owner_after parent_mode_after; then
:
else
cleanup_rc=1
fi
[[ "$parent_identity_after" == "$parent_identity_before" ]] || cleanup_rc=1
(( cleanup_rc == 0 )) || return 1
case "${_capture_signal-0}" in
130|143) return "$_capture_signal" ;;
esac
(( validation_rc == 0 )) || return 1
}
_k3slra1_remove_owned_capture() {
local path="${1-}" expected_identity="${2-}" canonical=''
local identity='' nlink='' size='' mtime='' type='' owner='' mode=''
(( $# == 2 )) || return 1
[[ -n "$expected_identity" ]] || return 1
_k3slra1_canonical_path "$path" canonical || return 1
[[ "$canonical" == "$path" ]] || return 1
_k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1
[[ "$identity" == "$expected_identity" ]] || return 1
[[ "$nlink" =~ ^[1-9][0-9]*$ ]] || return 1
[[ "$type" == 'regular file' ]] || return 1
_k3slra1_command /usr/bin/unlink "$path" >/dev/null 2>&1 || return 1
[[ ! -e "$path" ]] || return 1
[[ ! -L "$path" ]]
}
_k3slra1_remove_partial_capture() {
local path="${1-}" expected_device="${2-}" expected_identity="${3-}" canonical=''
local identity='' nlink='' size='' mtime='' type='' owner='' mode=''
(( $# == 3 )) || return 1
_k3slra1_canonical_path "$path" canonical || return 1
[[ "$canonical" == "$path" ]] || return 1
_k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1
[[ "$identity" == "$expected_identity" ]] || return 1
[[ "$type" == 'regular file' ]] || return 1
[[ "$nlink" == 1 ]] || return 1
[[ "$owner" == 0:0 ]] || return 1
[[ "$mode" == 600 ]] || return 1
[[ "${identity%%:*}" == "$expected_device" ]] || return 1
_k3slra1_command /usr/bin/unlink "$path" >/dev/null 2>&1 || return 1
[[ ! -e "$path" ]] || return 1
[[ ! -L "$path" ]]
}
_k3slra1_stderr_open_boundary() {
:
}
_k3slra1_sqlite_stdout_stage() {
local database="${1-}" capture_root="${2-}" stdout_path="${3-}" stderr_path="${4-}"
local _stage_parent_identity='' _stage_parent_nlink='' _stage_parent_size=''
local _stage_parent_mtime='' _stage_parent_type='' _stage_parent_owner='' _stage_parent_mode=''
local _stage_parent_fd_identity='' _stage_parent_fd_nlink='' _stage_parent_fd_size=''
local _stage_parent_fd_mtime='' _stage_parent_fd_type='' _stage_parent_fd_owner='' _stage_parent_fd_mode=''
local _stage_stdout_identity='' _stage_stdout_nlink='' _stage_stdout_size=''
local _stage_stdout_mtime='' _stage_stdout_type='' _stage_stdout_owner='' _stage_stdout_mode=''
local _stage_stdout_fd_identity='' _stage_stdout_fd_nlink='' _stage_stdout_fd_size=''
local _stage_stdout_fd_mtime='' _stage_stdout_fd_type='' _stage_stdout_fd_owner='' _stage_stdout_fd_mode=''
local stage_rc=1 cleanup_rc=0 validation_rc=0
(( $# == 4 )) || return 1
if _k3slra1_metadata_fields "$capture_root" _stage_parent_identity _stage_parent_nlink _stage_parent_size _stage_parent_mtime _stage_parent_type _stage_parent_owner _stage_parent_mode; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/6" _stage_parent_fd_identity _stage_parent_fd_nlink _stage_parent_fd_size _stage_parent_fd_mtime _stage_parent_fd_type _stage_parent_fd_owner _stage_parent_fd_mode; then
:
else
validation_rc=1
fi
if _k3slra1_metadata_fields "$stdout_path" _stage_stdout_identity _stage_stdout_nlink _stage_stdout_size _stage_stdout_mtime _stage_stdout_type _stage_stdout_owner _stage_stdout_mode; then
:
else
validation_rc=1
fi
if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/7" _stage_stdout_fd_identity _stage_stdout_fd_nlink _stage_stdout_fd_size _stage_stdout_fd_mtime _stage_stdout_fd_type _stage_stdout_fd_owner _stage_stdout_fd_mode; then
:
else
validation_rc=1
fi
[[ "$_stage_parent_identity" == "$_stage_parent_fd_identity" ]] || validation_rc=1
[[ "$_stage_parent_type" == directory ]] || validation_rc=1
[[ "$_stage_parent_fd_type" == directory ]] || validation_rc=1
[[ "$_stage_parent_owner" == 0:0 ]] || validation_rc=1
[[ "$_stage_parent_fd_owner" == 0:0 ]] || validation_rc=1
[[ "$_stage_parent_mode" == 700 ]] || validation_rc=1
[[ "$_stage_parent_fd_mode" == 700 ]] || validation_rc=1
[[ "$_stage_stdout_identity" == "$_stage_stdout_fd_identity" ]] || validation_rc=1
[[ "$_stage_stdout_type" == 'regular file' ]] || validation_rc=1
[[ "$_stage_stdout_fd_type" == 'regular file' ]] || validation_rc=1
[[ "$_stage_stdout_nlink" == 1 ]] || validation_rc=1
[[ "$_stage_stdout_fd_nlink" == 1 ]] || validation_rc=1
[[ "$_stage_stdout_size" == 0 ]] || validation_rc=1
[[ "$_stage_stdout_fd_size" == 0 ]] || validation_rc=1
[[ "$_stage_stdout_identity" != "$_stage_parent_identity" ]] || validation_rc=1
if (( validation_rc == 0 )); then
if _k3slra1_stderr_open_boundary; then
if _k3slra1_sqlite_capture_transaction "$database" "$capture_root" "$stdout_path" "$stderr_path" 8>"$stderr_path"; then
stage_rc=0
else
stage_rc=$?
fi
fi
fi
if (( _capture_entered == 0 )); then
_k3slra1_remove_partial_capture "$stdout_path" "${_stage_parent_identity%%:*}" "$_stage_stdout_identity" || cleanup_rc=1
fi
(( cleanup_rc == 0 )) || return 1
case "$stage_rc" in
0)
case "${_capture_signal-0}" in
130|143) return "$_capture_signal" ;;
esac
(( validation_rc == 0 )) || return 1
return 0
;;
130|143) return "$stage_rc" ;;
*)
if (( _capture_entered == 0 )); then
case "${_capture_signal-0}" in
130|143) return "$_capture_signal" ;;
esac
fi
return 1
;;
esac
}
_k3slra1_sqlite_quick_check() (
local bundle="${1-}" layout="${2-}" capture_root="${3-}" database_relative=''
local stdout_path='' stderr_path='' transaction_rc=1
local capture_canonical='' capture_identity='' capture_nlink='' capture_size='' capture_mtime=''
local capture_type='' capture_owner='' capture_mode=''
local _capture_entered=0 _capture_signal=0
(( $# == 3 )) || return 1
case "$layout" in
canonical) database_relative="$K3SLRA1_CANONICAL_DATABASE" ;;
legacy) database_relative="$K3SLRA1_LEGACY_DATABASE" ;;
*) return 1 ;;
esac
stdout_path="${capture_root}/sqlite.stdout"
stderr_path="${capture_root}/sqlite.stderr"
_k3slra1_canonical_path "$capture_root" capture_canonical || return 1
[[ "$capture_canonical" == "$capture_root" ]] || return 1
_k3slra1_metadata_fields "$capture_root" capture_identity capture_nlink capture_size capture_mtime capture_type capture_owner capture_mode || return 1
[[ "$capture_type" == directory ]] || return 1
[[ "$capture_owner" == 0:0 ]] || return 1
[[ "$capture_mode" == 700 ]] || return 1
[[ ! -e "$stdout_path" ]] || return 1
[[ ! -L "$stdout_path" ]] || return 1
[[ ! -e "$stderr_path" ]] || return 1
[[ ! -L "$stderr_path" ]] || return 1
umask 077
set -o noclobber
trap '_capture_signal=130; if (( transaction_rc == 0 )); then transaction_rc=130; fi' INT
trap '_capture_signal=143; if (( transaction_rc == 0 )); then transaction_rc=143; fi' TERM
if _k3slra1_sqlite_stdout_stage "${bundle}/pre/${database_relative#./}" "$capture_root" "$stdout_path" "$stderr_path" 2>/dev/null 6<"$capture_root" 7>"$stdout_path"; then
transaction_rc=0
else
transaction_rc=$?
fi
if (( _capture_signal != 0 && transaction_rc == 0 )); then
transaction_rc=$_capture_signal
fi
case "$transaction_rc" in
0) return 0 ;;
130|143) return "$transaction_rc" ;;
*) return 1 ;;
esac
)